Reorganize Fedora dotfiles and remove legacy profile
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
|||||||
plugin/
|
plugin/
|
||||||
.claude/
|
.claude/
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
target/
|
||||||
|
|||||||
@@ -1,41 +1,6 @@
|
|||||||
# the name by which the project can be referenced within Serena/when chatting with the LLM.
|
# the name by which the project can be referenced within Serena/when chatting with the LLM.
|
||||||
project_name: "dotfiles"
|
project_name: "dotfiles"
|
||||||
|
|
||||||
# list of languages for which language servers are started (LSP backend only); choose from:
|
|
||||||
# ada al angular ansible bash
|
|
||||||
# bsl clojure cpp cpp_ccls crystal
|
|
||||||
# csharp csharp_omnisharp cue dart elixir
|
|
||||||
# elm erlang fortran fsharp gdscript
|
|
||||||
# go groovy haskell haxe hlsl
|
|
||||||
# html java json julia kotlin
|
|
||||||
# latex lean4 lua luau markdown
|
|
||||||
# matlab msl nix ocaml pascal
|
|
||||||
# perl php php_phpactor php_phpantom powershell
|
|
||||||
# python python_jedi python_pyrefly python_ty r
|
|
||||||
# rego ruby ruby_solargraph rust scala
|
|
||||||
# scss solidity svelte swift systemverilog
|
|
||||||
# terraform toml typescript typescript_vts vue
|
|
||||||
# yaml zig
|
|
||||||
# (This list may be outdated; generated with scripts/print_language_list.py;
|
|
||||||
# For the current list, see values of Language enum here:
|
|
||||||
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py)
|
|
||||||
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
|
|
||||||
# Note:
|
|
||||||
# - For C, use cpp
|
|
||||||
# - For JavaScript, use typescript
|
|
||||||
# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root)
|
|
||||||
# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm)
|
|
||||||
# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three)
|
|
||||||
# - For Free Pascal/Lazarus, use pascal
|
|
||||||
# Special requirements:
|
|
||||||
# Some languages require additional setup/installations.
|
|
||||||
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
|
|
||||||
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
|
||||||
# The first language is the default language and the respective language server will be used as a fallback.
|
|
||||||
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
|
||||||
languages:
|
|
||||||
- lua
|
|
||||||
|
|
||||||
# the encoding used by text files in the project
|
# the encoding used by text files in the project
|
||||||
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
||||||
encoding: "utf-8"
|
encoding: "utf-8"
|
||||||
@@ -63,6 +28,13 @@ ls_specific_settings: {}
|
|||||||
|
|
||||||
# list of additional paths to ignore in this project.
|
# list of additional paths to ignore in this project.
|
||||||
# Same syntax as gitignore, so you can use * and **.
|
# Same syntax as gitignore, so you can use * and **.
|
||||||
|
# Important: quote patterns that start with `*`, otherwise YAML treats them as aliases.
|
||||||
|
# Example:
|
||||||
|
# ignored_paths:
|
||||||
|
# - "examples/**"
|
||||||
|
# - ".worktrees/**"
|
||||||
|
# - "**/bin/**"
|
||||||
|
# - "**/obj/**"
|
||||||
# Note: global ignored_paths from serena_config.yml are also applied additively.
|
# Note: global ignored_paths from serena_config.yml are also applied additively.
|
||||||
ignored_paths: []
|
ignored_paths: []
|
||||||
|
|
||||||
@@ -158,3 +130,38 @@ ls_additional_workspace_folders: []
|
|||||||
# - "./subproject2"
|
# - "./subproject2"
|
||||||
ls_workspace_folders:
|
ls_workspace_folders:
|
||||||
- .
|
- .
|
||||||
|
|
||||||
|
# list of language servers to start when using the LSP backend; choose from:
|
||||||
|
# ada al angular ansible bash
|
||||||
|
# bsl clojure cpp cpp_ccls crystal
|
||||||
|
# csharp csharp_omnisharp cue dart elixir
|
||||||
|
# elm erlang fortran fsharp gdscript
|
||||||
|
# go groovy haskell haxe hlsl
|
||||||
|
# html java json julia kotlin
|
||||||
|
# latex lean4 lua luau markdown
|
||||||
|
# matlab msl nix ocaml pascal
|
||||||
|
# perl php php_phpactor php_phpantom powershell
|
||||||
|
# python python_jedi python_pyrefly python_ty r
|
||||||
|
# rego ruby ruby_solargraph rust scala
|
||||||
|
# scss solidity svelte swift systemverilog
|
||||||
|
# terraform toml typescript typescript_vts vue
|
||||||
|
# yaml zig
|
||||||
|
# (This list may be outdated; generated with scripts/print_language_list.py;
|
||||||
|
# For the current list, see values of Language enum here:
|
||||||
|
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py)
|
||||||
|
# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
|
||||||
|
# Note:
|
||||||
|
# - For C, use cpp
|
||||||
|
# - For JavaScript, use typescript
|
||||||
|
# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root)
|
||||||
|
# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm)
|
||||||
|
# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three)
|
||||||
|
# - For Free Pascal/Lazarus, use pascal
|
||||||
|
# Special requirements:
|
||||||
|
# Some language servers require additional setup/installations.
|
||||||
|
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
|
||||||
|
# When using multiple language servers, the first language server that supports a given file will be used for that file.
|
||||||
|
# The first language server is the default language and the respective language server will be used as a fallback.
|
||||||
|
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
||||||
|
language_servers:
|
||||||
|
- lua
|
||||||
|
|||||||
87
AGENT.md
@@ -1,87 +0,0 @@
|
|||||||
# AGENT.md
|
|
||||||
|
|
||||||
## Про что этот репозиторий
|
|
||||||
|
|
||||||
`dotfiles` - личный репозиторий конфигураций для двух разных зон:
|
|
||||||
|
|
||||||
- `nvim/` - конфиг Neovim для основной development-среды.
|
|
||||||
- `fedora/` - текущий основной профиль рабочего стола Fedora с Niri.
|
|
||||||
- `bazzite/` - старый профиль Bazzite/Niri, который теперь нужен в основном как
|
|
||||||
legacy reference для миграции, сравнения и поддержки старых машин.
|
|
||||||
|
|
||||||
`CLAUDE.md` в этом репозитории покрывает в основном Neovim. Для desktop-задач
|
|
||||||
он не является полной картой проекта, поэтому сначала ориентируйся по
|
|
||||||
`README.md`, а затем по `fedora/README.md` или `bazzite/README.md`.
|
|
||||||
|
|
||||||
## Верхнеуровневая структура
|
|
||||||
|
|
||||||
- `README.md` - общий вход в репозиторий и краткая карта текущей структуры.
|
|
||||||
- `CLAUDE.md` - узкий guide по `nvim/`.
|
|
||||||
- `nvim/` - Neovim config:
|
|
||||||
- `init.lua` - точка входа;
|
|
||||||
- `lua/config/` - базовые options, keymaps, autocmds;
|
|
||||||
- `lua/plugins/` - конфиги плагинов;
|
|
||||||
- `lazy-lock.json` - зафиксированные версии плагинов.
|
|
||||||
- `fedora/` - основной desktop profile:
|
|
||||||
- `README.md` - каноническое описание профиля;
|
|
||||||
- `niri/config.kdl` - compositor/session behavior;
|
|
||||||
- `waybar/config.jsonc` и `waybar/style.css` - панель и стили;
|
|
||||||
- `khal-calendar/` и `mail-counter/` - Rust-модули для Waybar.
|
|
||||||
- `bazzite/` - legacy profile со структурой, близкой к `fedora/`.
|
|
||||||
|
|
||||||
Скрытые каталоги вроде `.git`, `.claude`, `.serena` считай tooling/infrastructure
|
|
||||||
metadata, а не рабочей частью конфигурации.
|
|
||||||
|
|
||||||
## Что читать для контекста
|
|
||||||
|
|
||||||
Всегда начинай с `README.md`.
|
|
||||||
|
|
||||||
Дальше маршрут такой:
|
|
||||||
|
|
||||||
- Если задача про Neovim:
|
|
||||||
1. `CLAUDE.md`
|
|
||||||
2. `nvim/init.lua`
|
|
||||||
3. нужные файлы из `nvim/lua/config/` или `nvim/lua/plugins/`
|
|
||||||
|
|
||||||
- Если задача про текущую Fedora-машину, Niri, Waybar, wallpaper, Steam,
|
|
||||||
Bottles, FlClash или desktop behavior:
|
|
||||||
1. `fedora/README.md`
|
|
||||||
2. нужный целевой конфиг, обычно один из:
|
|
||||||
- `fedora/niri/config.kdl`
|
|
||||||
- `fedora/waybar/config.jsonc`
|
|
||||||
- `fedora/waybar/style.css`
|
|
||||||
- `fedora/fuzzel/fuzzel.ini`
|
|
||||||
- `fedora/xsettingsd/xsettingsd.conf`
|
|
||||||
|
|
||||||
- Если задача про старую Bazzite-конфигурацию или миграцию между Bazzite и
|
|
||||||
Fedora:
|
|
||||||
1. `bazzite/README.md`
|
|
||||||
2. затем сравнивай с соответствующим файлом в `fedora/`
|
|
||||||
|
|
||||||
- Если задача про кастомные Waybar-модули:
|
|
||||||
1. `fedora/khal-calendar/README.md` или `bazzite/khal-calendar/README.md`
|
|
||||||
2. `fedora/khal-calendar/Cargo.toml` или `bazzite/khal-calendar/Cargo.toml`
|
|
||||||
3. `fedora/mail-counter/README.md` или `bazzite/mail-counter/README.md`
|
|
||||||
4. `fedora/mail-counter/Cargo.toml` или `bazzite/mail-counter/Cargo.toml`
|
|
||||||
|
|
||||||
## Repo-specific правила
|
|
||||||
|
|
||||||
- По умолчанию считай `fedora/` текущим и основным направлением.
|
|
||||||
- Не переноси автоматически старые предположения из `bazzite/` в `fedora/`.
|
|
||||||
- Если пользователь говорит просто "на федоре", "в desktop-конфиге" или
|
|
||||||
"в niri", сначала смотри `fedora/`.
|
|
||||||
- Если пользователь просит исторический контекст, сравнение или миграцию,
|
|
||||||
используй `bazzite/` как reference, но не как source of truth для новых
|
|
||||||
изменений.
|
|
||||||
- Не считай `CLAUDE.md` полной документацией по всему репозиторию: он уже, чем
|
|
||||||
реальная структура проекта.
|
|
||||||
|
|
||||||
## Как работать безопасно
|
|
||||||
|
|
||||||
- Для desktop-задач не ограничивайся общими рассуждениями: сначала читай
|
|
||||||
subtree README, потом точечный конфиг.
|
|
||||||
- Не дублируй содержимое `fedora/README.md` и `bazzite/README.md` в новых
|
|
||||||
документах без необходимости; эти файлы уже являются каноническими описаниями
|
|
||||||
профилей.
|
|
||||||
- Если в рабочем дереве есть несвязанные изменения, не откатывай их и не
|
|
||||||
расширяй задачу за пределы нужного subtree без явного запроса.
|
|
||||||
38
CLAUDE.md
@@ -1,38 +0,0 @@
|
|||||||
# Dotfiles
|
|
||||||
|
|
||||||
Personal dotfiles repository for development environment configuration.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
- `nvim/` — Neovim configuration (symlinked to `~/.config/nvim`)
|
|
||||||
|
|
||||||
## Neovim
|
|
||||||
|
|
||||||
Config built for Neovim 0.11+ using native APIs (`vim.lsp.config`, `vim.lsp.enable`, built-in treesitter).
|
|
||||||
|
|
||||||
**Plugin manager:** lazy.nvim (auto-bootstraps on first launch).
|
|
||||||
|
|
||||||
**Languages:** Rust, Zig, TypeScript/JavaScript, C/C++.
|
|
||||||
|
|
||||||
**LSP servers:**
|
|
||||||
- `rust-analyzer` — via rustaceanvim (install with `rustup component add rust-analyzer`)
|
|
||||||
- `clangd` — via mason (auto-installed)
|
|
||||||
- `ts_ls` — via mason (auto-installed)
|
|
||||||
- `zls` — manual install (`brew install zls`)
|
|
||||||
|
|
||||||
**Key plugins:** telescope, treesitter, nvim-cmp, bufferline, neo-tree, gitsigns, lazygit, lualine, which-key, persistence, alabaster theme.
|
|
||||||
|
|
||||||
**Leader key:** Space.
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Symlink nvim config
|
|
||||||
ln -s ~/Docs/Projects/dotfiles/nvim ~/.config/nvim
|
|
||||||
|
|
||||||
# Install lazygit
|
|
||||||
brew install lazygit
|
|
||||||
|
|
||||||
# First nvim launch will auto-install plugins, then run:
|
|
||||||
# :TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash
|
|
||||||
```
|
|
||||||
199
README.md
@@ -1,108 +1,129 @@
|
|||||||
# Dotfiles
|
# Dotfiles
|
||||||
|
|
||||||
Personal dotfiles for development environment configuration.
|
Личный репозиторий конфигураций Neovim и Linux desktop-сессии на Fedora.
|
||||||
|
|
||||||
## Structure
|
## Структура
|
||||||
|
|
||||||
|
Сейчас в репозитории поддерживаются два рабочих слоя:
|
||||||
|
|
||||||
|
- `nvim/` — конфигурация Neovim 0.11+;
|
||||||
|
- `fedora/` — основной профиль Fedora с Niri и QuickShell.
|
||||||
|
|
||||||
|
Новые полноценные системные профили добавляются отдельными каталогами верхнего
|
||||||
|
уровня: `arch/`, `debian/`, `laptop/` и т. п. Файлы текущего профиля не нужно
|
||||||
|
смешивать между системами.
|
||||||
|
|
||||||
|
Основные части профиля Fedora:
|
||||||
|
|
||||||
|
| Путь | Назначение |
|
||||||
|
| --- | --- |
|
||||||
|
| `fedora/niri/config.kdl` | Композитор, автозапуск, правила окон и хоткеи. |
|
||||||
|
| `fedora/quickshell/control-center/` | Bar, control center, media popup, OSD и notifications. |
|
||||||
|
| `fedora/quickshell/scripts/` | Скрипты погоды и NVIDIA GPU для QuickShell. |
|
||||||
|
| `fedora/systemd/user/` | User unit для QuickShell. |
|
||||||
|
| `fedora/khal-calendar/` | Rust-модуль календаря. |
|
||||||
|
| `fedora/mail-counter/` | Rust-счётчик непрочитанных писем Thunderbird. |
|
||||||
|
| `fedora/wallpapers/wallpaper.png` | Канонический wallpaper профиля. |
|
||||||
|
| `fedora/packages.txt` | Список пакетов Fedora. |
|
||||||
|
| `install.sh` | Переносимая установка ссылок и Rust-бинарников. |
|
||||||
|
|
||||||
|
Скрытые каталоги вроде `.git`, `.claude` и `.serena` относятся к инструментам
|
||||||
|
разработки, а не к desktop-профилю.
|
||||||
|
|
||||||
|
## Установка Fedora
|
||||||
|
|
||||||
|
Установить зависимости из [fedora/packages.txt](fedora/packages.txt):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dnf install -y $(grep -vE '^[[:space:]]*(#|$)' fedora/packages.txt)
|
||||||
```
|
```
|
||||||
nvim/ # Neovim config (symlink to ~/.config/nvim)
|
|
||||||
├── init.lua
|
|
||||||
└── lua/
|
|
||||||
├── config/
|
|
||||||
│ ├── autocmds.lua
|
|
||||||
│ ├── keymaps.lua
|
|
||||||
│ └── options.lua
|
|
||||||
└── plugins/
|
|
||||||
├── bufferline.lua
|
|
||||||
├── cmp.lua
|
|
||||||
├── colorscheme.lua
|
|
||||||
├── editor.lua
|
|
||||||
├── git.lua
|
|
||||||
├── lsp.lua
|
|
||||||
├── lualine.lua
|
|
||||||
├── session.lua
|
|
||||||
├── telescope.lua
|
|
||||||
└── treesitter.lua
|
|
||||||
|
|
||||||
bazzite/ # Bazzite (Fedora) + Niri compositor configs
|
Для GPU нужен настроенный NVIDIA-драйвер с рабочим `nvidia-smi`. Затем запустить
|
||||||
├── niri/config.kdl
|
установщик из любой директории:
|
||||||
├── btop/btop.conf
|
|
||||||
├── glow/glow.yml
|
```bash
|
||||||
├── gtk-3.0/
|
./install.sh
|
||||||
│ ├── colors.css
|
|
||||||
│ ├── gtk.css
|
|
||||||
│ └── settings.ini
|
|
||||||
├── gtk-4.0/
|
|
||||||
│ ├── colors.css
|
|
||||||
│ ├── gtk.css
|
|
||||||
│ └── settings.ini
|
|
||||||
├── fuzzel/fuzzel.ini
|
|
||||||
├── waybar/
|
|
||||||
│ ├── config.jsonc
|
|
||||||
│ └── style.css
|
|
||||||
├── xsettingsd/xsettingsd.conf
|
|
||||||
├── environment.d/intel-gtk-fix.conf
|
|
||||||
└── autostart/steam.desktop
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Скрипт определяет свой корень автоматически, подключает конфигурации Fedora и
|
||||||
|
Neovim через ссылки в `$HOME/.config`, создаёт
|
||||||
|
`$HOME/.local/bin`, подключает QuickShell и systemd unit, создаёт ссылку
|
||||||
|
`$HOME/.config/wallpaper.png`, собирает оба Rust-модуля и устанавливает их в
|
||||||
|
`$HOME/.local/bin`.
|
||||||
|
|
||||||
|
Обычные файлы конфигурации не должны молча затираться установщиком: если на
|
||||||
|
месте ссылки уже лежит реальный файл или каталог, скрипт остановится и сообщит
|
||||||
|
об этом.
|
||||||
|
|
||||||
|
## QuickShell
|
||||||
|
|
||||||
|
Niri запускает `quickshell-control-center.service`, а unit запускает shell из
|
||||||
|
стабильной ссылки `$HOME/.config/quickshell/control-center`. После изменения
|
||||||
|
QML применить конфигурацию можно так:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user restart quickshell-control-center.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Ручной запуск и IPC:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qs -p "$HOME/.config/quickshell/control-center"
|
||||||
|
qs ipc -p "$HOME/.config/quickshell/control-center" call controlcenter toggle
|
||||||
|
qs ipc -p "$HOME/.config/quickshell/control-center" call controlcenter close
|
||||||
|
qs ipc -p "$HOME/.config/quickshell/control-center" call osd volume_up
|
||||||
|
```
|
||||||
|
|
||||||
|
Bar показывает погоду, загрузку GPU, CPU, память, root filesystem, раскладку,
|
||||||
|
аудиовход, календарь и остальные интерактивные индикаторы. Температурные пороги
|
||||||
|
настраиваются в control center; отдельная старая панель больше не используется.
|
||||||
|
|
||||||
|
## Rust-модули
|
||||||
|
|
||||||
|
Установщик выполняет сборку автоматически. Для ручной пересборки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
cargo build --release --manifest-path fedora/khal-calendar/Cargo.toml
|
||||||
|
install -m 755 fedora/khal-calendar/target/release/khal-calendar "$HOME/.local/bin/khal-calendar"
|
||||||
|
cargo build --release --manifest-path fedora/mail-counter/Cargo.toml
|
||||||
|
install -m 755 fedora/mail-counter/target/release/mail-counter "$HOME/.local/bin/mail-counter"
|
||||||
|
```
|
||||||
|
|
||||||
|
Календарь использует `khal`, а mail-counter читает Thunderbird
|
||||||
|
`global-messages-db.sqlite` и отдаёт JSON, который читает QuickShell.
|
||||||
|
|
||||||
## Neovim
|
## Neovim
|
||||||
|
|
||||||
Requires Neovim 0.11+ — uses native APIs (`vim.lsp.config`, `vim.lsp.enable`, built-in treesitter).
|
Конфигурация использует lazy.nvim, native LSP API и встроенный Treesitter.
|
||||||
|
Leader — Space. Поддерживаемые языки: Rust, Zig, TypeScript/JavaScript и C/C++.
|
||||||
|
|
||||||
**Plugin manager:** lazy.nvim (auto-bootstraps on first launch).
|
LSP-серверы:
|
||||||
|
|
||||||
**Leader key:** Space.
|
- `rust-analyzer` через rustaceanvim;
|
||||||
|
- `clangd` и `ts_ls` через Mason;
|
||||||
|
- `zls` устанавливается отдельно в системе.
|
||||||
|
|
||||||
### Languages
|
Первый запуск Neovim установит плагины. Затем можно установить парсеры:
|
||||||
|
|
||||||
Rust, Zig, TypeScript/JavaScript, C/C++.
|
```vim
|
||||||
|
:TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash
|
||||||
### LSP servers
|
|
||||||
|
|
||||||
| Server | Language | Install |
|
|
||||||
|---|---|---|
|
|
||||||
| rust-analyzer | Rust | `rustup component add rust-analyzer` (via rustaceanvim) |
|
|
||||||
| clangd | C/C++ | auto-installed via mason |
|
|
||||||
| ts_ls | TypeScript/JS | auto-installed via mason |
|
|
||||||
| zls | Zig | `brew install zls` |
|
|
||||||
|
|
||||||
### Key plugins
|
|
||||||
|
|
||||||
telescope, treesitter, nvim-cmp, bufferline, neo-tree, gitsigns, lazygit, lualine, which-key, persistence, alabaster theme.
|
|
||||||
|
|
||||||
## Bazzite
|
|
||||||
|
|
||||||
Configs for Bazzite (Fedora Atomic) with Niri Wayland compositor.
|
|
||||||
|
|
||||||
| Config | Description |
|
|
||||||
|---|---|
|
|
||||||
| `niri/config.kdl` | Niri compositor |
|
|
||||||
| `fuzzel/fuzzel.ini` | App launcher |
|
|
||||||
| `waybar/` | Top panel (config + style) |
|
|
||||||
| `btop/btop.conf` | System monitor |
|
|
||||||
| `glow/glow.yml` | Terminal markdown viewer |
|
|
||||||
| `gtk-3.0/`, `gtk-4.0/` | GTK theme and colors |
|
|
||||||
| `xsettingsd/xsettingsd.conf` | X11/XWayland settings (fonts, theme) |
|
|
||||||
| `environment.d/intel-gtk-fix.conf` | Intel GPU environment fix |
|
|
||||||
| `autostart/steam.desktop` | Steam autostart |
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
### macOS (Neovim)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ln -s ~/Docs/Projects/dotfiles/nvim ~/.config/nvim
|
|
||||||
brew install lazygit
|
|
||||||
|
|
||||||
# First nvim launch will auto-install plugins, then run:
|
|
||||||
# :TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bazzite
|
Если нужно подключить только Neovim вручную:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Symlink configs to ~/.config/
|
ln -sfn "$PWD/nvim" "${XDG_CONFIG_HOME:-$HOME/.config}/nvim"
|
||||||
for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do
|
|
||||||
ln -sf ~/Docs/Projects/dotfiles/bazzite/$dir ~/.config/$dir
|
|
||||||
done
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Правила работы с репозиторием
|
||||||
|
|
||||||
|
- Сначала читать этот `README.md`, затем целевой конфиг.
|
||||||
|
- `fedora/` — текущий source of truth для Fedora, Niri и QuickShell.
|
||||||
|
- Незакоммиченные правки пользователя сохранять; несвязанные файлы не откатывать.
|
||||||
|
- Проверять runtime-конфигурацию, если поведение системы расходится с текстом
|
||||||
|
checkout.
|
||||||
|
- Не добавлять секреты, токены, кэши, логи и машинный мусор.
|
||||||
|
- Markdown-документация живёт только в корневом `README.md`; новые инструкции
|
||||||
|
добавлять туда, а не создавать отдельные README.
|
||||||
|
|||||||
BIN
bazzite/.DS_Store
vendored
@@ -1,113 +0,0 @@
|
|||||||
# Конфиги рабочего стола Bazzite
|
|
||||||
|
|
||||||
Эта папка содержит конфигурацию рабочего стола Bazzite для Wayland-сессии на
|
|
||||||
Niri. Идея в том, чтобы подключать эти файлы в `~/.config` на Bazzite-машине и
|
|
||||||
держать живую конфигурацию рабочего стола синхронизированной с этим
|
|
||||||
репозиторием.
|
|
||||||
|
|
||||||
## Что здесь настроено
|
|
||||||
|
|
||||||
| Путь | Назначение |
|
|
||||||
|---|---|
|
|
||||||
| `niri/config.kdl` | Конфиг Niri: ввод, монитор, раскладка окон, автозапуск, правила окон, хоткеи. |
|
|
||||||
| `waybar/` | Верхняя панель: конфиг, CSS в стиле Catppuccin и custom-модули. |
|
|
||||||
| `waybar/scripts/gpu.sh` | Модуль Waybar для загрузки и температуры NVIDIA GPU через `nvidia-smi`. |
|
|
||||||
| `waybar/scripts/weather.sh` | Модуль Waybar с погодой через `wttr.in`. |
|
|
||||||
| `khal-calendar/` | Rust-версия календарного модуля Waybar. |
|
|
||||||
| `mail-counter/` | Rust-модуль Waybar для счетчика непрочитанных писем Thunderbird. |
|
|
||||||
| `fuzzel/fuzzel.ini` | Тема лаунчера Fuzzel на цветах Catppuccin Latte. |
|
|
||||||
| `btop/btop.conf` | Настройки системного монитора btop. |
|
|
||||||
| `glow/glow.yml` | Настройки терминального Markdown-viewer Glow. |
|
|
||||||
| `gtk-3.0/`, `gtk-4.0/` | GTK-настройки и цветовые файлы Breeze/Catppuccin. |
|
|
||||||
| `xsettingsd/xsettingsd.conf` | Настройки GTK, курсора, иконок, шрифта и DPI для X11/XWayland-приложений. |
|
|
||||||
| `environment.d/intel-gtk-fix.conf` | Переменная окружения сессии: `GSK_RENDERER=gl`. |
|
|
||||||
| `autostart/steam.desktop` | Автозапуск Steam через Bazzite Steam wrapper. |
|
|
||||||
| `wallpapers/image.png` | Текущая картинка рабочего стола для `swaybg`. |
|
|
||||||
|
|
||||||
## Как это работает
|
|
||||||
|
|
||||||
Niri запускает `swaybg` и `waybar` из `niri/config.kdl`. `swaybg` рисует
|
|
||||||
wallpaper, Waybar поднимает:
|
|
||||||
|
|
||||||
- встроенные Niri-модули для рабочих столов, заголовка окна и раскладки
|
|
||||||
клавиатуры;
|
|
||||||
- системные модули для звука, сети, CPU, памяти, температуры, диска, privacy,
|
|
||||||
power profile и tray;
|
|
||||||
- custom-модули для почты Thunderbird, погоды, NVIDIA GPU и календаря из
|
|
||||||
`khal`.
|
|
||||||
|
|
||||||
Календарный модуль печатает JSON для Waybar и показывает Pango-tooltip с текущим
|
|
||||||
месяцем, подсвеченными днями с событиями и ближайшими событиями из `khal`.
|
|
||||||
Активная реализация сейчас - скомпилированный Rust-бинарник:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
"exec": "~/.config/waybar/scripts/khal-calendar"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Ожидаемые программы
|
|
||||||
|
|
||||||
Для полной работы конфигурации на Bazzite ожидаются:
|
|
||||||
|
|
||||||
- `niri`
|
|
||||||
- `waybar`
|
|
||||||
- `fuzzel`
|
|
||||||
- `btop`
|
|
||||||
- `glow`
|
|
||||||
- `xsettingsd`
|
|
||||||
- `alacritty`
|
|
||||||
- `swaybg`
|
|
||||||
- `khal`, `ikhal`, `vdirsyncer`
|
|
||||||
- `nvidia-smi`
|
|
||||||
- `curl`
|
|
||||||
- `cargo` для пересборки `khal-calendar` и `mail-counter`
|
|
||||||
|
|
||||||
## Установка
|
|
||||||
|
|
||||||
Подключить директории в `~/.config`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do
|
|
||||||
ln -sfn ~/dotfiles/bazzite/$dir ~/.config/$dir
|
|
||||||
done
|
|
||||||
mkdir -p ~/Pictures/Wallpapers
|
|
||||||
ln -sfn ~/dotfiles/bazzite/wallpapers/image.png ~/Pictures/Wallpapers/image.png
|
|
||||||
```
|
|
||||||
|
|
||||||
Если репозиторий лежит не в `~/dotfiles`, путь нужно поправить.
|
|
||||||
|
|
||||||
## Сборка календарного модуля
|
|
||||||
|
|
||||||
Собрать и установить Rust-бинарник календаря на Bazzite:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/khal-calendar
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar
|
|
||||||
```
|
|
||||||
|
|
||||||
Исходники остаются в `khal-calendar/`; установленный бинарник лежит в
|
|
||||||
`~/.config/waybar/scripts/`.
|
|
||||||
|
|
||||||
## Сборка почтового модуля
|
|
||||||
|
|
||||||
Собрать и установить Rust-бинарник счетчика писем на Bazzite:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/mail-counter
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail
|
|
||||||
```
|
|
||||||
|
|
||||||
Модуль читает `global-messages-db.sqlite` из профиля Thunderbird и печатает JSON
|
|
||||||
для `custom/mail` в Waybar.
|
|
||||||
|
|
||||||
## Перезагрузка
|
|
||||||
|
|
||||||
После изменения конфига или CSS Waybar:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pkill -SIGUSR2 waybar
|
|
||||||
```
|
|
||||||
|
|
||||||
Если Waybar не подхватил изменения, нужно перезапустить Waybar вручную или
|
|
||||||
перезапустить Niri-сессию.
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Name=Steam
|
|
||||||
Comment=Application for managing and playing games on Steam
|
|
||||||
Comment[pt_BR]=Aplicativo para jogar e gerenciar jogos no Steam
|
|
||||||
Comment[bg]=Приложение за ръководене и пускане на игри в Steam
|
|
||||||
Comment[cs]=Aplikace pro spravování a hraní her ve službě Steam
|
|
||||||
Comment[da]=Applikation til at håndtere og spille spil på Steam
|
|
||||||
Comment[nl]=Applicatie voor het beheer en het spelen van games op Steam
|
|
||||||
Comment[fi]=Steamin pelien hallintaan ja pelaamiseen tarkoitettu sovellus
|
|
||||||
Comment[fr]=Application de gestion et d'utilisation des jeux sur Steam
|
|
||||||
Comment[de]=Anwendung zum Verwalten und Spielen von Spielen auf Steam
|
|
||||||
Comment[el]=Εφαρμογή διαχείρισης παιχνιδιών στο Steam
|
|
||||||
Comment[hu]=Alkalmazás a Steames játékok futtatásához és kezeléséhez
|
|
||||||
Comment[it]=Applicazione per la gestione e l'esecuzione di giochi su Steam
|
|
||||||
Comment[ja]=Steam 上でゲームを管理&プレイするためのアプリケーション
|
|
||||||
Comment[ko]=Steam에 있는 게임을 관리하고 플레이할 수 있는 응용 프로그램
|
|
||||||
Comment[no]=Program for å administrere og spille spill på Steam
|
|
||||||
Comment[pt_PT]=Aplicação para organizar e executar jogos no Steam
|
|
||||||
Comment[pl]=Aplikacja do zarządzania i uruchamiania gier na platformie Steam
|
|
||||||
Comment[ro]=Aplicație pentru administrarea și jucatul jocurilor pe Steam
|
|
||||||
Comment[ru]=Приложение для игр и управления играми в Steam
|
|
||||||
Comment[es]=Aplicación para administrar y ejecutar juegos en Steam
|
|
||||||
Comment[sv]=Ett program för att hantera samt spela spel på Steam
|
|
||||||
Comment[zh_CN]=管理和进行 Steam 游戏的应用程序
|
|
||||||
Comment[zh_TW]=管理並執行 Steam 遊戲的應用程式
|
|
||||||
Comment[th]=โปรแกรมสำหรับจัดการและเล่นเกมบน Steam
|
|
||||||
Comment[tr]=Steam üzerinden oyun oynama ve düzenleme uygulaması
|
|
||||||
Comment[uk]=Програма для керування іграми та запуску ігор у Steam
|
|
||||||
Comment[vi]=Ứng dụng để quản lý và chơi trò chơi trên Steam
|
|
||||||
Exec=/usr/bin/bazzite-steam -silent %U
|
|
||||||
Icon=steam
|
|
||||||
Terminal=false
|
|
||||||
Type=Application
|
|
||||||
Categories=Network;FileTransfer;Game;
|
|
||||||
MimeType=x-scheme-handler/steam;x-scheme-handler/steamlink;
|
|
||||||
Actions=Store;Community;Library;Servers;Screenshots;News;Settings;BigPicture;Friends;
|
|
||||||
X-Desktop-File-Install-Version=0.28
|
|
||||||
|
|
||||||
[Desktop Action Store]
|
|
||||||
Name=Store
|
|
||||||
Name[pt_BR]=Loja
|
|
||||||
Name[bg]=Магазин
|
|
||||||
Name[cs]=Obchod
|
|
||||||
Name[da]=Butik
|
|
||||||
Name[nl]=Winkel
|
|
||||||
Name[fi]=Kauppa
|
|
||||||
Name[fr]=Magasin
|
|
||||||
Name[de]=Shop
|
|
||||||
Name[el]=ΚΑΤΑΣΤΗΜΑ
|
|
||||||
Name[hu]=Áruház
|
|
||||||
Name[it]=Negozio
|
|
||||||
Name[ja]=ストア
|
|
||||||
Name[ko]=상점
|
|
||||||
Name[no]=Butikk
|
|
||||||
Name[pt_PT]=Loja
|
|
||||||
Name[pl]=Sklep
|
|
||||||
Name[ro]=Magazin
|
|
||||||
Name[ru]=Магазин
|
|
||||||
Name[es]=Tienda
|
|
||||||
Name[sv]=Butik
|
|
||||||
Name[zh_CN]=商店
|
|
||||||
Name[zh_TW]=商店
|
|
||||||
Name[th]=ร้านค้า
|
|
||||||
Name[tr]=Mağaza
|
|
||||||
Name[uk]=Крамниця
|
|
||||||
Name[vi]=Cửa hàng
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://store
|
|
||||||
|
|
||||||
[Desktop Action Community]
|
|
||||||
Name=Community
|
|
||||||
Name[pt_BR]=Comunidade
|
|
||||||
Name[bg]=Общност
|
|
||||||
Name[cs]=Komunita
|
|
||||||
Name[da]=Fællesskab
|
|
||||||
Name[nl]=Community
|
|
||||||
Name[fi]=Yhteisö
|
|
||||||
Name[fr]=Communauté
|
|
||||||
Name[de]=Community
|
|
||||||
Name[el]=Κοινότητα
|
|
||||||
Name[hu]=Közösség
|
|
||||||
Name[it]=Comunità
|
|
||||||
Name[ja]=コミュニティ
|
|
||||||
Name[ko]=커뮤니티
|
|
||||||
Name[no]=Samfunn
|
|
||||||
Name[pt_PT]=Comunidade
|
|
||||||
Name[pl]=Społeczność
|
|
||||||
Name[ro]=Comunitate
|
|
||||||
Name[ru]=Сообщество
|
|
||||||
Name[es]=Comunidad
|
|
||||||
Name[sv]=Gemenskap
|
|
||||||
Name[zh_CN]=社区
|
|
||||||
Name[zh_TW]=社群
|
|
||||||
Name[th]=ชุมชน
|
|
||||||
Name[tr]=Topluluk
|
|
||||||
Name[uk]=Спільнота
|
|
||||||
Name[vi]=Cộng đồng
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://url/CommunityHome/
|
|
||||||
|
|
||||||
[Desktop Action Library]
|
|
||||||
Name=Library
|
|
||||||
Name[pt_BR]=Biblioteca
|
|
||||||
Name[bg]=Библиотека
|
|
||||||
Name[cs]=Knihovna
|
|
||||||
Name[da]=Bibliotek
|
|
||||||
Name[nl]=Bibliotheek
|
|
||||||
Name[fi]=Kokoelma
|
|
||||||
Name[fr]=Bibliothèque
|
|
||||||
Name[de]=Bibliothek
|
|
||||||
Name[el]=Συλλογή
|
|
||||||
Name[hu]=Könyvtár
|
|
||||||
Name[it]=Libreria
|
|
||||||
Name[ja]=ライブラリ
|
|
||||||
Name[ko]=라이브러리
|
|
||||||
Name[no]=Bibliotek
|
|
||||||
Name[pt_PT]=Biblioteca
|
|
||||||
Name[pl]=Biblioteka
|
|
||||||
Name[ro]=Colecţie
|
|
||||||
Name[ru]=Библиотека
|
|
||||||
Name[es]=Biblioteca
|
|
||||||
Name[sv]=Bibliotek
|
|
||||||
Name[zh_CN]=库
|
|
||||||
Name[zh_TW]=收藏庫
|
|
||||||
Name[th]=คลัง
|
|
||||||
Name[tr]=Kütüphane
|
|
||||||
Name[uk]=Бібліотека
|
|
||||||
Name[vi]=Thư viện
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/games
|
|
||||||
|
|
||||||
[Desktop Action Servers]
|
|
||||||
Name=Servers
|
|
||||||
Name[pt_BR]=Servidores
|
|
||||||
Name[bg]=Сървъри
|
|
||||||
Name[cs]=Servery
|
|
||||||
Name[da]=Servere
|
|
||||||
Name[nl]=Servers
|
|
||||||
Name[fi]=Palvelimet
|
|
||||||
Name[fr]=Serveurs
|
|
||||||
Name[de]=Server
|
|
||||||
Name[el]=Διακομιστές
|
|
||||||
Name[hu]=Szerverek
|
|
||||||
Name[it]=Server
|
|
||||||
Name[ja]=サーバー
|
|
||||||
Name[ko]=서버
|
|
||||||
Name[no]=Tjenere
|
|
||||||
Name[pt_PT]=Servidores
|
|
||||||
Name[pl]=Serwery
|
|
||||||
Name[ro]=Servere
|
|
||||||
Name[ru]=Серверы
|
|
||||||
Name[es]=Servidores
|
|
||||||
Name[sv]=Servrar
|
|
||||||
Name[zh_CN]=服务器
|
|
||||||
Name[zh_TW]=伺服器
|
|
||||||
Name[th]=เซิร์ฟเวอร์
|
|
||||||
Name[tr]=Sunucular
|
|
||||||
Name[uk]=Сервери
|
|
||||||
Name[vi]=Máy chủ
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/servers
|
|
||||||
|
|
||||||
[Desktop Action Screenshots]
|
|
||||||
Name=Screenshots
|
|
||||||
Name[pt_BR]=Capturas de tela
|
|
||||||
Name[bg]=Снимки
|
|
||||||
Name[cs]=Snímky obrazovky
|
|
||||||
Name[da]=Skærmbilleder
|
|
||||||
Name[nl]=Screenshots
|
|
||||||
Name[fi]=Kuvankaappaukset
|
|
||||||
Name[fr]=Captures d'écran
|
|
||||||
Name[de]=Screenshots
|
|
||||||
Name[el]=Φωτογραφίες
|
|
||||||
Name[hu]=Képernyőmentések
|
|
||||||
Name[it]=Screenshot
|
|
||||||
Name[ja]=スクリーンショット
|
|
||||||
Name[ko]=스크린샷
|
|
||||||
Name[no]=Skjermbilder
|
|
||||||
Name[pt_PT]=Capturas de ecrã
|
|
||||||
Name[pl]=Zrzuty ekranu
|
|
||||||
Name[ro]=Capturi de ecran
|
|
||||||
Name[ru]=Скриншоты
|
|
||||||
Name[es]=Capturas
|
|
||||||
Name[sv]=Skärmdumpar
|
|
||||||
Name[zh_CN]=截图
|
|
||||||
Name[zh_TW]=螢幕擷圖
|
|
||||||
Name[th]=ภาพหน้าจอ
|
|
||||||
Name[tr]=Ekran Görüntüleri
|
|
||||||
Name[uk]=Скріншоти
|
|
||||||
Name[vi]=Ảnh chụp
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/screenshots
|
|
||||||
|
|
||||||
[Desktop Action News]
|
|
||||||
Name=News
|
|
||||||
Name[pt_BR]=Notícias
|
|
||||||
Name[bg]=Новини
|
|
||||||
Name[cs]=Zprávy
|
|
||||||
Name[da]=Nyheder
|
|
||||||
Name[nl]=Nieuws
|
|
||||||
Name[fi]=Uutiset
|
|
||||||
Name[fr]=Actualités
|
|
||||||
Name[de]=Neuigkeiten
|
|
||||||
Name[el]=Νέα
|
|
||||||
Name[hu]=Hírek
|
|
||||||
Name[it]=Notizie
|
|
||||||
Name[ja]=ニュース
|
|
||||||
Name[ko]=뉴스
|
|
||||||
Name[no]=Nyheter
|
|
||||||
Name[pt_PT]=Novidades
|
|
||||||
Name[pl]=Aktualności
|
|
||||||
Name[ro]=Știri
|
|
||||||
Name[ru]=Новости
|
|
||||||
Name[es]=Noticias
|
|
||||||
Name[sv]=Nyheter
|
|
||||||
Name[zh_CN]=新闻
|
|
||||||
Name[zh_TW]=新聞
|
|
||||||
Name[th]=ข่าวสาร
|
|
||||||
Name[tr]=Haberler
|
|
||||||
Name[uk]=Новини
|
|
||||||
Name[vi]=Tin tức
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://openurl/https://store.steampowered.com/news
|
|
||||||
|
|
||||||
[Desktop Action Settings]
|
|
||||||
Name=Settings
|
|
||||||
Name[pt_BR]=Configurações
|
|
||||||
Name[bg]=Настройки
|
|
||||||
Name[cs]=Nastavení
|
|
||||||
Name[da]=Indstillinger
|
|
||||||
Name[nl]=Instellingen
|
|
||||||
Name[fi]=Asetukset
|
|
||||||
Name[fr]=Paramètres
|
|
||||||
Name[de]=Einstellungen
|
|
||||||
Name[el]=Ρυθμίσεις
|
|
||||||
Name[hu]=Beállítások
|
|
||||||
Name[it]=Impostazioni
|
|
||||||
Name[ja]=設定
|
|
||||||
Name[ko]=설정
|
|
||||||
Name[no]=Innstillinger
|
|
||||||
Name[pt_PT]=Definições
|
|
||||||
Name[pl]=Ustawienia
|
|
||||||
Name[ro]=Setări
|
|
||||||
Name[ru]=Настройки
|
|
||||||
Name[es]=Parámetros
|
|
||||||
Name[sv]=Inställningar
|
|
||||||
Name[zh_CN]=设置
|
|
||||||
Name[zh_TW]=設定
|
|
||||||
Name[th]=การตั้งค่า
|
|
||||||
Name[tr]=Ayarlar
|
|
||||||
Name[uk]=Налаштування
|
|
||||||
Name[vi]=Thiết lập
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/settings
|
|
||||||
|
|
||||||
[Desktop Action BigPicture]
|
|
||||||
Name=Big Picture
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/bigpicture
|
|
||||||
|
|
||||||
[Desktop Action Friends]
|
|
||||||
Name=Friends
|
|
||||||
Name[pt_BR]=Amigos
|
|
||||||
Name[bg]=Приятели
|
|
||||||
Name[cs]=Přátelé
|
|
||||||
Name[da]=Venner
|
|
||||||
Name[nl]=Vrienden
|
|
||||||
Name[fi]=Kaverit
|
|
||||||
Name[fr]=Amis
|
|
||||||
Name[de]=Freunde
|
|
||||||
Name[el]=Φίλοι
|
|
||||||
Name[hu]=Barátok
|
|
||||||
Name[it]=Amici
|
|
||||||
Name[ja]=フレンド
|
|
||||||
Name[ko]=친구
|
|
||||||
Name[no]=Venner
|
|
||||||
Name[pt_PT]=Amigos
|
|
||||||
Name[pl]=Znajomi
|
|
||||||
Name[ro]=Prieteni
|
|
||||||
Name[ru]=Друзья
|
|
||||||
Name[es]=Amigos
|
|
||||||
Name[sv]=Vänner
|
|
||||||
Name[zh_CN]=好友
|
|
||||||
Name[zh_TW]=好友
|
|
||||||
Name[th]=เพื่อน
|
|
||||||
Name[tr]=Arkadaşlar
|
|
||||||
Name[uk]=Друзі
|
|
||||||
Name[vi]=Bạn bè
|
|
||||||
Exec=/usr/bin/bazzite-steam steam://open/friends
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
#? Config file for btop v. 1.4.5
|
|
||||||
|
|
||||||
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
|
|
||||||
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
|
|
||||||
color_theme = "Default"
|
|
||||||
|
|
||||||
#* If the theme set background should be shown, set to False if you want terminal background transparency.
|
|
||||||
theme_background = True
|
|
||||||
|
|
||||||
#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false.
|
|
||||||
truecolor = True
|
|
||||||
|
|
||||||
#* Set to true to force tty mode regardless if a real tty has been detected or not.
|
|
||||||
#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols.
|
|
||||||
force_tty = False
|
|
||||||
|
|
||||||
#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets.
|
|
||||||
#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box.
|
|
||||||
#* Use whitespace " " as separator between different presets.
|
|
||||||
#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty"
|
|
||||||
presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"
|
|
||||||
|
|
||||||
#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists.
|
|
||||||
#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift.
|
|
||||||
vim_keys = False
|
|
||||||
|
|
||||||
#* Rounded corners on boxes, is ignored if TTY mode is ON.
|
|
||||||
rounded_corners = True
|
|
||||||
|
|
||||||
#* Default symbols to use for graph creation, "braille", "block" or "tty".
|
|
||||||
#* "braille" offers the highest resolution but might not be included in all fonts.
|
|
||||||
#* "block" has half the resolution of braille but uses more common characters.
|
|
||||||
#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY.
|
|
||||||
#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view.
|
|
||||||
graph_symbol = "braille"
|
|
||||||
|
|
||||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
|
||||||
graph_symbol_cpu = "default"
|
|
||||||
|
|
||||||
# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty".
|
|
||||||
graph_symbol_gpu = "default"
|
|
||||||
|
|
||||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
|
||||||
graph_symbol_mem = "default"
|
|
||||||
|
|
||||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
|
||||||
graph_symbol_net = "default"
|
|
||||||
|
|
||||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
|
||||||
graph_symbol_proc = "default"
|
|
||||||
|
|
||||||
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
|
|
||||||
shown_boxes = "proc cpu mem net"
|
|
||||||
|
|
||||||
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
|
||||||
update_ms = 1000
|
|
||||||
|
|
||||||
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct",
|
|
||||||
#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly.
|
|
||||||
proc_sorting = "memory"
|
|
||||||
|
|
||||||
#* Reverse sorting order, True or False.
|
|
||||||
proc_reversed = False
|
|
||||||
|
|
||||||
#* Show processes as a tree.
|
|
||||||
proc_tree = False
|
|
||||||
|
|
||||||
#* Use the cpu graph colors in the process list.
|
|
||||||
proc_colors = True
|
|
||||||
|
|
||||||
#* Use a darkening gradient in the process list.
|
|
||||||
proc_gradient = True
|
|
||||||
|
|
||||||
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
|
||||||
proc_per_core = False
|
|
||||||
|
|
||||||
#* Show process memory as bytes instead of percent.
|
|
||||||
proc_mem_bytes = True
|
|
||||||
|
|
||||||
#* Show cpu graph for each process.
|
|
||||||
proc_cpu_graphs = True
|
|
||||||
|
|
||||||
#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate)
|
|
||||||
proc_info_smaps = False
|
|
||||||
|
|
||||||
#* Show proc box on left side of screen instead of right.
|
|
||||||
proc_left = False
|
|
||||||
|
|
||||||
#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop).
|
|
||||||
proc_filter_kernel = False
|
|
||||||
|
|
||||||
#* In tree-view, always accumulate child process resources in the parent process.
|
|
||||||
proc_aggregate = False
|
|
||||||
|
|
||||||
#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available.
|
|
||||||
#* Select from a list of detected attributes from the options menu.
|
|
||||||
cpu_graph_upper = "Auto"
|
|
||||||
|
|
||||||
#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available.
|
|
||||||
#* Select from a list of detected attributes from the options menu.
|
|
||||||
cpu_graph_lower = "Auto"
|
|
||||||
|
|
||||||
#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off".
|
|
||||||
show_gpu_info = "Auto"
|
|
||||||
|
|
||||||
#* Toggles if the lower CPU graph should be inverted.
|
|
||||||
cpu_invert_lower = True
|
|
||||||
|
|
||||||
#* Set to True to completely disable the lower CPU graph.
|
|
||||||
cpu_single_graph = False
|
|
||||||
|
|
||||||
#* Show cpu box at bottom of screen instead of top.
|
|
||||||
cpu_bottom = False
|
|
||||||
|
|
||||||
#* Shows the system uptime in the CPU box.
|
|
||||||
show_uptime = True
|
|
||||||
|
|
||||||
#* Shows the CPU package current power consumption in watts. Requires running `make setcap` or `make setuid` or running with sudo.
|
|
||||||
show_cpu_watts = True
|
|
||||||
|
|
||||||
#* Show cpu temperature.
|
|
||||||
check_temp = True
|
|
||||||
|
|
||||||
#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors.
|
|
||||||
cpu_sensor = "Auto"
|
|
||||||
|
|
||||||
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found.
|
|
||||||
show_coretemp = True
|
|
||||||
|
|
||||||
#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core.
|
|
||||||
#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine.
|
|
||||||
#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries.
|
|
||||||
#* Example: "4:0 5:1 6:3"
|
|
||||||
cpu_core_map = ""
|
|
||||||
|
|
||||||
#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine".
|
|
||||||
temp_scale = "celsius"
|
|
||||||
|
|
||||||
#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024.
|
|
||||||
base_10_sizes = False
|
|
||||||
|
|
||||||
#* Show CPU frequency.
|
|
||||||
show_cpu_freq = True
|
|
||||||
|
|
||||||
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
|
|
||||||
#* Special formatting: /host = hostname | /user = username | /uptime = system uptime
|
|
||||||
clock_format = "%X"
|
|
||||||
|
|
||||||
#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort.
|
|
||||||
background_update = True
|
|
||||||
|
|
||||||
#* Custom cpu model name, empty string to disable.
|
|
||||||
custom_cpu_name = ""
|
|
||||||
|
|
||||||
#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ".
|
|
||||||
#* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user"
|
|
||||||
disks_filter = ""
|
|
||||||
|
|
||||||
#* Show graphs instead of meters for memory values.
|
|
||||||
mem_graphs = True
|
|
||||||
|
|
||||||
#* Show mem box below net box instead of above.
|
|
||||||
mem_below_net = False
|
|
||||||
|
|
||||||
#* Count ZFS ARC in cached and available memory.
|
|
||||||
zfs_arc_cached = True
|
|
||||||
|
|
||||||
#* If swap memory should be shown in memory box.
|
|
||||||
show_swap = True
|
|
||||||
|
|
||||||
#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk.
|
|
||||||
swap_disk = True
|
|
||||||
|
|
||||||
#* If mem box should be split to also show disks info.
|
|
||||||
show_disks = True
|
|
||||||
|
|
||||||
#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar.
|
|
||||||
only_physical = True
|
|
||||||
|
|
||||||
#* Read disks list from /etc/fstab. This also disables only_physical.
|
|
||||||
use_fstab = True
|
|
||||||
|
|
||||||
#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool)
|
|
||||||
zfs_hide_datasets = False
|
|
||||||
|
|
||||||
#* Set to true to show available disk space for privileged users.
|
|
||||||
disk_free_priv = False
|
|
||||||
|
|
||||||
#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view.
|
|
||||||
show_io_stat = True
|
|
||||||
|
|
||||||
#* Toggles io mode for disks, showing big graphs for disk read/write speeds.
|
|
||||||
io_mode = False
|
|
||||||
|
|
||||||
#* Set to True to show combined read/write io graphs in io mode.
|
|
||||||
io_graph_combined = False
|
|
||||||
|
|
||||||
#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ".
|
|
||||||
#* Example: "/mnt/media:100 /:20 /boot:1".
|
|
||||||
io_graph_speeds = ""
|
|
||||||
|
|
||||||
#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False.
|
|
||||||
net_download = 100
|
|
||||||
|
|
||||||
net_upload = 100
|
|
||||||
|
|
||||||
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
|
|
||||||
net_auto = True
|
|
||||||
|
|
||||||
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
|
|
||||||
net_sync = True
|
|
||||||
|
|
||||||
#* Starts with the Network Interface specified here.
|
|
||||||
net_iface = ""
|
|
||||||
|
|
||||||
#* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes.
|
|
||||||
base_10_bitrate = "Auto"
|
|
||||||
|
|
||||||
#* Show battery stats in top right if battery is present.
|
|
||||||
show_battery = True
|
|
||||||
|
|
||||||
#* Which battery to use if multiple are present. "Auto" for auto detection.
|
|
||||||
selected_battery = "Auto"
|
|
||||||
|
|
||||||
#* Show power stats of battery next to charge indicator.
|
|
||||||
show_battery_watts = True
|
|
||||||
|
|
||||||
#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG".
|
|
||||||
#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info.
|
|
||||||
log_level = "WARNING"
|
|
||||||
|
|
||||||
#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards.
|
|
||||||
nvml_measure_pcie_speeds = True
|
|
||||||
|
|
||||||
#* Measure PCIe throughput on AMD cards, may impact performance on certain cards.
|
|
||||||
rsmi_measure_pcie_speeds = True
|
|
||||||
|
|
||||||
#* Horizontally mirror the GPU graph.
|
|
||||||
gpu_mirror_graph = True
|
|
||||||
|
|
||||||
#* Custom gpu0 model name, empty string to disable.
|
|
||||||
custom_gpu_name0 = ""
|
|
||||||
|
|
||||||
#* Custom gpu1 model name, empty string to disable.
|
|
||||||
custom_gpu_name1 = ""
|
|
||||||
|
|
||||||
#* Custom gpu2 model name, empty string to disable.
|
|
||||||
custom_gpu_name2 = ""
|
|
||||||
|
|
||||||
#* Custom gpu3 model name, empty string to disable.
|
|
||||||
custom_gpu_name3 = ""
|
|
||||||
|
|
||||||
#* Custom gpu4 model name, empty string to disable.
|
|
||||||
custom_gpu_name4 = ""
|
|
||||||
|
|
||||||
#* Custom gpu5 model name, empty string to disable.
|
|
||||||
custom_gpu_name5 = ""
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
GSK_RENDERER=gl
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Catppuccin Latte (Blue) + 70% opacity background
|
|
||||||
|
|
||||||
[colors]
|
|
||||||
background=eff1f5b3
|
|
||||||
text=4c4f69ff
|
|
||||||
prompt=5c5f77ff
|
|
||||||
placeholder=8c8fa1ff
|
|
||||||
input=4c4f69ff
|
|
||||||
match=1e66f5ff
|
|
||||||
selection=acb0beff
|
|
||||||
selection-text=4c4f69ff
|
|
||||||
selection-match=1e66f5ff
|
|
||||||
counter=8c8fa1ff
|
|
||||||
border=f38ba8ff
|
|
||||||
|
|
||||||
[border]
|
|
||||||
width=2
|
|
||||||
radius=6
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# style name or JSON path (default "auto")
|
|
||||||
style: "auto"
|
|
||||||
# mouse support (TUI-mode only)
|
|
||||||
mouse: false
|
|
||||||
# use pager to display markdown
|
|
||||||
pager: false
|
|
||||||
# word-wrap at width
|
|
||||||
width: 80
|
|
||||||
# show all files, including hidden and ignored.
|
|
||||||
all: false
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
@define-color borders_breeze #bcbebf;
|
|
||||||
@define-color content_view_bg_breeze #ffffff;
|
|
||||||
@define-color error_color_backdrop_breeze #da4453;
|
|
||||||
@define-color error_color_breeze #da4453;
|
|
||||||
@define-color error_color_insensitive_backdrop_breeze #f0b1b8;
|
|
||||||
@define-color error_color_insensitive_breeze #f0b1b8;
|
|
||||||
@define-color insensitive_base_color_breeze #f3f3f3;
|
|
||||||
@define-color insensitive_base_fg_color_breeze #aaabac;
|
|
||||||
@define-color insensitive_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_borders_breeze #d2d4d6;
|
|
||||||
@define-color insensitive_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_selected_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_selected_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_unfocused_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_unfocused_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_unfocused_selected_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_unfocused_selected_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color link_color_breeze #2980b9;
|
|
||||||
@define-color link_visited_color_breeze #9b59b6;
|
|
||||||
@define-color success_color_backdrop_breeze #27ae60;
|
|
||||||
@define-color success_color_breeze #27ae60;
|
|
||||||
@define-color success_color_insensitive_backdrop_breeze #abd8be;
|
|
||||||
@define-color success_color_insensitive_breeze #abd8be;
|
|
||||||
@define-color theme_base_color_breeze #ffffff;
|
|
||||||
@define-color theme_bg_color_breeze #eff0f1;
|
|
||||||
@define-color theme_button_background_backdrop_breeze #fcfcfc;
|
|
||||||
@define-color theme_button_background_backdrop_insensitive_breeze #f0f0f0;
|
|
||||||
@define-color theme_button_background_insensitive_breeze #f0f0f0;
|
|
||||||
@define-color theme_button_background_normal_breeze #fcfcfc;
|
|
||||||
@define-color theme_button_decoration_focus_backdrop_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_focus_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_focus_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_hover_backdrop_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_hover_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_hover_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_foreground_active_backdrop_breeze #232629;
|
|
||||||
@define-color theme_button_foreground_active_backdrop_insensitive_breeze #a0a1a3;
|
|
||||||
@define-color theme_button_foreground_active_breeze #ffffff;
|
|
||||||
@define-color theme_button_foreground_active_insensitive_breeze #a0a1a3;
|
|
||||||
@define-color theme_button_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_button_foreground_backdrop_insensitive_breeze #a8a9aa;
|
|
||||||
@define-color theme_button_foreground_insensitive_breeze #a8a9aa;
|
|
||||||
@define-color theme_button_foreground_normal_breeze #232629;
|
|
||||||
@define-color theme_fg_color_breeze #232629;
|
|
||||||
@define-color theme_header_background_backdrop_breeze #eff0f1;
|
|
||||||
@define-color theme_header_background_breeze #dee0e2;
|
|
||||||
@define-color theme_header_background_light_breeze #eff0f1;
|
|
||||||
@define-color theme_header_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_insensitive_backdrop_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_insensitive_breeze #232629;
|
|
||||||
@define-color theme_hovering_selected_bg_color_breeze #3daee9;
|
|
||||||
@define-color theme_selected_bg_color_breeze #3daee9;
|
|
||||||
@define-color theme_selected_fg_color_breeze #ffffff;
|
|
||||||
@define-color theme_text_color_breeze #232629;
|
|
||||||
@define-color theme_titlebar_background_backdrop_breeze #eff0f1;
|
|
||||||
@define-color theme_titlebar_background_breeze #dee0e2;
|
|
||||||
@define-color theme_titlebar_background_light_breeze #eff0f1;
|
|
||||||
@define-color theme_titlebar_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_insensitive_breeze #232629;
|
|
||||||
@define-color theme_unfocused_base_color_breeze #ffffff;
|
|
||||||
@define-color theme_unfocused_bg_color_breeze #eff0f1;
|
|
||||||
@define-color theme_unfocused_fg_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_selected_bg_color_alt_breeze #c2e0f5;
|
|
||||||
@define-color theme_unfocused_selected_bg_color_breeze #c2e0f5;
|
|
||||||
@define-color theme_unfocused_selected_fg_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_text_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_view_bg_color_breeze #f3f3f3;
|
|
||||||
@define-color theme_unfocused_view_text_color_breeze #aaabac;
|
|
||||||
@define-color theme_view_active_decoration_color_breeze #3daee9;
|
|
||||||
@define-color theme_view_hover_decoration_color_breeze #3daee9;
|
|
||||||
@define-color tooltip_background_breeze #f7f7f7;
|
|
||||||
@define-color tooltip_border_breeze #c2c3c4;
|
|
||||||
@define-color tooltip_text_breeze #232629;
|
|
||||||
@define-color unfocused_borders_breeze #bcbebf;
|
|
||||||
@define-color unfocused_insensitive_borders_breeze #d2d4d6;
|
|
||||||
@define-color warning_color_backdrop_breeze #f67400;
|
|
||||||
@define-color warning_color_breeze #f67400;
|
|
||||||
@define-color warning_color_insensitive_backdrop_breeze #fbc289;
|
|
||||||
@define-color warning_color_insensitive_breeze #fbc289;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
@import 'colors.css';
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[Settings]
|
|
||||||
gtk-application-prefer-dark-theme=false
|
|
||||||
gtk-button-images=true
|
|
||||||
gtk-cursor-blink=true
|
|
||||||
gtk-cursor-blink-time=1000
|
|
||||||
gtk-cursor-theme-name=breeze_cursors
|
|
||||||
gtk-cursor-theme-size=24
|
|
||||||
gtk-decoration-layout=icon:minimize,maximize,close
|
|
||||||
gtk-enable-animations=true
|
|
||||||
gtk-font-name=Noto Sans, 10
|
|
||||||
gtk-icon-theme-name=breeze
|
|
||||||
gtk-menu-images=true
|
|
||||||
gtk-modules=colorreload-gtk-module
|
|
||||||
gtk-primary-button-warps-slider=true
|
|
||||||
gtk-sound-theme-name=ocean
|
|
||||||
gtk-toolbar-style=3
|
|
||||||
gtk-xft-dpi=98304
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
@define-color borders_breeze #bcbebf;
|
|
||||||
@define-color content_view_bg_breeze #ffffff;
|
|
||||||
@define-color error_color_backdrop_breeze #da4453;
|
|
||||||
@define-color error_color_breeze #da4453;
|
|
||||||
@define-color error_color_insensitive_backdrop_breeze #f0b1b8;
|
|
||||||
@define-color error_color_insensitive_breeze #f0b1b8;
|
|
||||||
@define-color insensitive_base_color_breeze #f3f3f3;
|
|
||||||
@define-color insensitive_base_fg_color_breeze #aaabac;
|
|
||||||
@define-color insensitive_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_borders_breeze #d2d4d6;
|
|
||||||
@define-color insensitive_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_selected_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_selected_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_unfocused_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_unfocused_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color insensitive_unfocused_selected_bg_color_breeze #e3e5e7;
|
|
||||||
@define-color insensitive_unfocused_selected_fg_color_breeze #a0a1a3;
|
|
||||||
@define-color link_color_breeze #2980b9;
|
|
||||||
@define-color link_visited_color_breeze #9b59b6;
|
|
||||||
@define-color success_color_backdrop_breeze #27ae60;
|
|
||||||
@define-color success_color_breeze #27ae60;
|
|
||||||
@define-color success_color_insensitive_backdrop_breeze #abd8be;
|
|
||||||
@define-color success_color_insensitive_breeze #abd8be;
|
|
||||||
@define-color theme_base_color_breeze #ffffff;
|
|
||||||
@define-color theme_bg_color_breeze #eff0f1;
|
|
||||||
@define-color theme_button_background_backdrop_breeze #fcfcfc;
|
|
||||||
@define-color theme_button_background_backdrop_insensitive_breeze #f0f0f0;
|
|
||||||
@define-color theme_button_background_insensitive_breeze #f0f0f0;
|
|
||||||
@define-color theme_button_background_normal_breeze #fcfcfc;
|
|
||||||
@define-color theme_button_decoration_focus_backdrop_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_focus_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_focus_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_hover_backdrop_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_decoration_hover_breeze #3daee9;
|
|
||||||
@define-color theme_button_decoration_hover_insensitive_breeze #a2d8f3;
|
|
||||||
@define-color theme_button_foreground_active_backdrop_breeze #232629;
|
|
||||||
@define-color theme_button_foreground_active_backdrop_insensitive_breeze #a0a1a3;
|
|
||||||
@define-color theme_button_foreground_active_breeze #ffffff;
|
|
||||||
@define-color theme_button_foreground_active_insensitive_breeze #a0a1a3;
|
|
||||||
@define-color theme_button_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_button_foreground_backdrop_insensitive_breeze #a8a9aa;
|
|
||||||
@define-color theme_button_foreground_insensitive_breeze #a8a9aa;
|
|
||||||
@define-color theme_button_foreground_normal_breeze #232629;
|
|
||||||
@define-color theme_fg_color_breeze #232629;
|
|
||||||
@define-color theme_header_background_backdrop_breeze #eff0f1;
|
|
||||||
@define-color theme_header_background_breeze #dee0e2;
|
|
||||||
@define-color theme_header_background_light_breeze #eff0f1;
|
|
||||||
@define-color theme_header_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_insensitive_backdrop_breeze #232629;
|
|
||||||
@define-color theme_header_foreground_insensitive_breeze #232629;
|
|
||||||
@define-color theme_hovering_selected_bg_color_breeze #3daee9;
|
|
||||||
@define-color theme_selected_bg_color_breeze #3daee9;
|
|
||||||
@define-color theme_selected_fg_color_breeze #ffffff;
|
|
||||||
@define-color theme_text_color_breeze #232629;
|
|
||||||
@define-color theme_titlebar_background_backdrop_breeze #eff0f1;
|
|
||||||
@define-color theme_titlebar_background_breeze #dee0e2;
|
|
||||||
@define-color theme_titlebar_background_light_breeze #eff0f1;
|
|
||||||
@define-color theme_titlebar_foreground_backdrop_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #232629;
|
|
||||||
@define-color theme_titlebar_foreground_insensitive_breeze #232629;
|
|
||||||
@define-color theme_unfocused_base_color_breeze #ffffff;
|
|
||||||
@define-color theme_unfocused_bg_color_breeze #eff0f1;
|
|
||||||
@define-color theme_unfocused_fg_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_selected_bg_color_alt_breeze #c2e0f5;
|
|
||||||
@define-color theme_unfocused_selected_bg_color_breeze #c2e0f5;
|
|
||||||
@define-color theme_unfocused_selected_fg_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_text_color_breeze #232629;
|
|
||||||
@define-color theme_unfocused_view_bg_color_breeze #f3f3f3;
|
|
||||||
@define-color theme_unfocused_view_text_color_breeze #aaabac;
|
|
||||||
@define-color theme_view_active_decoration_color_breeze #3daee9;
|
|
||||||
@define-color theme_view_hover_decoration_color_breeze #3daee9;
|
|
||||||
@define-color tooltip_background_breeze #f7f7f7;
|
|
||||||
@define-color tooltip_border_breeze #c2c3c4;
|
|
||||||
@define-color tooltip_text_breeze #232629;
|
|
||||||
@define-color unfocused_borders_breeze #bcbebf;
|
|
||||||
@define-color unfocused_insensitive_borders_breeze #d2d4d6;
|
|
||||||
@define-color warning_color_backdrop_breeze #f67400;
|
|
||||||
@define-color warning_color_breeze #f67400;
|
|
||||||
@define-color warning_color_insensitive_backdrop_breeze #fbc289;
|
|
||||||
@define-color warning_color_insensitive_breeze #fbc289;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
@import 'colors.css';
|
|
||||||
@import 'kde_window_geometry.css';
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
[Settings]
|
|
||||||
gtk-application-prefer-dark-theme=false
|
|
||||||
gtk-cursor-blink=true
|
|
||||||
gtk-cursor-blink-time=1000
|
|
||||||
gtk-cursor-theme-name=breeze_cursors
|
|
||||||
gtk-cursor-theme-size=24
|
|
||||||
gtk-decoration-layout=icon:minimize,maximize,close
|
|
||||||
gtk-enable-animations=true
|
|
||||||
gtk-font-name=Noto Sans, 10
|
|
||||||
gtk-icon-theme-name=breeze
|
|
||||||
gtk-modules=colorreload-gtk-module
|
|
||||||
gtk-primary-button-warps-slider=true
|
|
||||||
gtk-sound-theme-name=ocean
|
|
||||||
gtk-xft-dpi=98304
|
|
||||||
1
bazzite/khal-calendar/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/target/
|
|
||||||
383
bazzite/khal-calendar/Cargo.lock
generated
@@ -1,383 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android_system_properties"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bumpalo"
|
|
||||||
version = "3.20.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.2.61"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
|
|
||||||
dependencies = [
|
|
||||||
"find-msvc-tools",
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
|
||||||
dependencies = [
|
|
||||||
"iana-time-zone",
|
|
||||||
"js-sys",
|
|
||||||
"num-traits",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "core-foundation-sys"
|
|
||||||
version = "0.8.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "find-msvc-tools"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-core"
|
|
||||||
version = "0.3.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-task"
|
|
||||||
version = "0.3.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-util"
|
|
||||||
version = "0.3.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
"futures-task",
|
|
||||||
"pin-project-lite",
|
|
||||||
"slab",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone"
|
|
||||||
version = "0.1.65"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
|
||||||
dependencies = [
|
|
||||||
"android_system_properties",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"iana-time-zone-haiku",
|
|
||||||
"js-sys",
|
|
||||||
"log",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone-haiku"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "js-sys"
|
|
||||||
version = "0.3.97"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"futures-util",
|
|
||||||
"once_cell",
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "khal-calendar"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.186"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.21.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-lite"
|
|
||||||
version = "0.2.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.106"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustversion"
|
|
||||||
version = "1.0.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
||||||
dependencies = [
|
|
||||||
"serde_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_core"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
||||||
dependencies = [
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.149"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"memchr",
|
|
||||||
"serde",
|
|
||||||
"serde_core",
|
|
||||||
"zmij",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slab"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.24"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen"
|
|
||||||
version = "0.2.120"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
"rustversion",
|
|
||||||
"wasm-bindgen-macro",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro"
|
|
||||||
version = "0.2.120"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"wasm-bindgen-macro-support",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro-support"
|
|
||||||
version = "0.2.120"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41"
|
|
||||||
dependencies = [
|
|
||||||
"bumpalo",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-shared"
|
|
||||||
version = "0.2.120"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-core"
|
|
||||||
version = "0.62.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
|
||||||
dependencies = [
|
|
||||||
"windows-implement",
|
|
||||||
"windows-interface",
|
|
||||||
"windows-link",
|
|
||||||
"windows-result",
|
|
||||||
"windows-strings",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-implement"
|
|
||||||
version = "0.60.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-interface"
|
|
||||||
version = "0.59.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-link"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zmij"
|
|
||||||
version = "1.0.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "khal-calendar"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
chrono = "0.4"
|
|
||||||
serde_json = "1"
|
|
||||||
|
|
||||||
[lints.rust]
|
|
||||||
unsafe_code = "warn"
|
|
||||||
|
|
||||||
[lints.clippy]
|
|
||||||
all = "warn"
|
|
||||||
pedantic = "warn"
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# khal-calendar
|
|
||||||
|
|
||||||
Waybar custom calendar module that prints JSON with the current time and a Pango
|
|
||||||
tooltip. Event days and upcoming events are read from `khal`.
|
|
||||||
|
|
||||||
## Build On Bazzite
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/khal-calendar
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar
|
|
||||||
```
|
|
||||||
|
|
||||||
Waybar config should call the compiled binary:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
"exec": "~/.config/waybar/scripts/khal-calendar"
|
|
||||||
```
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
use std::{
|
|
||||||
collections::BTreeSet,
|
|
||||||
process::{Command, Stdio},
|
|
||||||
thread::sleep,
|
|
||||||
time::{Duration, Instant},
|
|
||||||
};
|
|
||||||
|
|
||||||
use chrono::{Datelike, Local, NaiveDate, Timelike};
|
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
const COMMAND_TIMEOUT: Duration = Duration::from_secs(5);
|
|
||||||
const MONTH_NAMES: [&str; 13] = [
|
|
||||||
"",
|
|
||||||
"January",
|
|
||||||
"February",
|
|
||||||
"March",
|
|
||||||
"April",
|
|
||||||
"May",
|
|
||||||
"June",
|
|
||||||
"July",
|
|
||||||
"August",
|
|
||||||
"September",
|
|
||||||
"October",
|
|
||||||
"November",
|
|
||||||
"December",
|
|
||||||
];
|
|
||||||
|
|
||||||
fn run_khal(args: &[&str]) -> Option<String> {
|
|
||||||
let mut child = Command::new("khal")
|
|
||||||
.args(args)
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::null())
|
|
||||||
.spawn()
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
let deadline = Instant::now() + COMMAND_TIMEOUT;
|
|
||||||
loop {
|
|
||||||
match child.try_wait() {
|
|
||||||
Ok(Some(_status)) => {
|
|
||||||
let output = child.wait_with_output().ok()?;
|
|
||||||
return Some(String::from_utf8_lossy(&output.stdout).trim().to_owned());
|
|
||||||
}
|
|
||||||
Ok(None) if Instant::now() >= deadline => {
|
|
||||||
let _ = child.kill();
|
|
||||||
let _ = child.wait();
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Ok(None) => sleep(Duration::from_millis(25)),
|
|
||||||
Err(_) => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn days_in_month(year: i32, month: u32) -> u32 {
|
|
||||||
let (next_year, next_month) = if month == 12 {
|
|
||||||
(year + 1, 1)
|
|
||||||
} else {
|
|
||||||
(year, month + 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
NaiveDate::from_ymd_opt(next_year, next_month, 1)
|
|
||||||
.and_then(|date| date.pred_opt())
|
|
||||||
.map_or(31, |date| date.day())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_event_days(year: i32, month: u32) -> BTreeSet<u32> {
|
|
||||||
let Some(first) = NaiveDate::from_ymd_opt(year, month, 1) else {
|
|
||||||
return BTreeSet::new();
|
|
||||||
};
|
|
||||||
let Some(last) = NaiveDate::from_ymd_opt(year, month, days_in_month(year, month)) else {
|
|
||||||
return BTreeSet::new();
|
|
||||||
};
|
|
||||||
|
|
||||||
let start = first.format("%d.%m.%Y").to_string();
|
|
||||||
let end = last.format("%d.%m.%Y").to_string();
|
|
||||||
let Some(stdout) = run_khal(&[
|
|
||||||
"list",
|
|
||||||
&start,
|
|
||||||
&end,
|
|
||||||
"--format",
|
|
||||||
"{start-date}",
|
|
||||||
"--day-format",
|
|
||||||
"",
|
|
||||||
]) else {
|
|
||||||
return BTreeSet::new();
|
|
||||||
};
|
|
||||||
|
|
||||||
stdout
|
|
||||||
.lines()
|
|
||||||
.filter_map(|line| NaiveDate::parse_from_str(line.trim(), "%d.%m.%Y").ok())
|
|
||||||
.filter(|date| date.month() == month)
|
|
||||||
.map(|date| date.day())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_calendar(year: i32, month: u32, event_days: &BTreeSet<u32>, today: NaiveDate) -> String {
|
|
||||||
let Some(first) = NaiveDate::from_ymd_opt(year, month, 1) else {
|
|
||||||
return String::new();
|
|
||||||
};
|
|
||||||
|
|
||||||
let month_name = MONTH_NAMES
|
|
||||||
.get(month as usize)
|
|
||||||
.copied()
|
|
||||||
.unwrap_or("Unknown");
|
|
||||||
let mut lines = vec![
|
|
||||||
format!(r##"<span color="#1e66f5"><b>{month_name} {year}</b></span>"##),
|
|
||||||
r##"<span color="#8839ef"><b>Mo Tu We Th Fr Sa Su</b></span>"##.to_owned(),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut week = vec![" ".to_owned(); (first.weekday().number_from_monday() - 1) as usize];
|
|
||||||
for day in 1..=days_in_month(year, month) {
|
|
||||||
let day_string = if day == today.day() && month == today.month() && year == today.year() {
|
|
||||||
format!(r##"<span color="#d20f39"><b><u>{day:2}</u></b></span>"##)
|
|
||||||
} else if event_days.contains(&day) {
|
|
||||||
format!(r##"<span color="#40a02b"><b>{day:2}</b></span>"##)
|
|
||||||
} else {
|
|
||||||
format!(r##"<span color="#4c4f69">{day:2}</span>"##)
|
|
||||||
};
|
|
||||||
week.push(day_string);
|
|
||||||
|
|
||||||
if week.len() == 7 {
|
|
||||||
lines.push(week.join(" "));
|
|
||||||
week.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !week.is_empty() {
|
|
||||||
week.resize(7, " ".to_owned());
|
|
||||||
lines.push(week.join(" "));
|
|
||||||
}
|
|
||||||
|
|
||||||
lines.join("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_upcoming_events() -> String {
|
|
||||||
run_khal(&["list", "today", "7d"]).unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let now = Local::now();
|
|
||||||
let today = now.date_naive();
|
|
||||||
let event_days = get_event_days(today.year(), today.month());
|
|
||||||
let calendar = build_calendar(today.year(), today.month(), &event_days, today);
|
|
||||||
let events = get_upcoming_events();
|
|
||||||
|
|
||||||
let tooltip = if events.is_empty() {
|
|
||||||
calendar
|
|
||||||
} else {
|
|
||||||
format!(r##"{calendar}\n\n<span color="#1e66f5"><b>Upcoming</b></span>\n{events}"##)
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
json!({
|
|
||||||
"text": format!("{:02}:{:02}", now.hour(), now.minute()),
|
|
||||||
"tooltip": tooltip,
|
|
||||||
"alt": today.format("%Y-%m-%d").to_string(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
1
bazzite/mail-counter/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/target/
|
|
||||||
213
bazzite/mail-counter/Cargo.lock
generated
@@ -1,213 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "2.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.2.61"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
|
|
||||||
dependencies = [
|
|
||||||
"find-msvc-tools",
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fallible-iterator"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fallible-streaming-iterator"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "find-msvc-tools"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foldhash"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.15.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
|
||||||
dependencies = [
|
|
||||||
"foldhash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashlink"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
|
||||||
dependencies = [
|
|
||||||
"hashbrown",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libsqlite3-sys"
|
|
||||||
version = "0.35.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mail-counter"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"rusqlite",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.33"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.106"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rusqlite"
|
|
||||||
version = "0.37.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"fallible-iterator",
|
|
||||||
"fallible-streaming-iterator",
|
|
||||||
"hashlink",
|
|
||||||
"libsqlite3-sys",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
||||||
dependencies = [
|
|
||||||
"serde_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_core"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
||||||
dependencies = [
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.228"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.149"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"memchr",
|
|
||||||
"serde",
|
|
||||||
"serde_core",
|
|
||||||
"zmij",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.15.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.117"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.24"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcpkg"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zmij"
|
|
||||||
version = "1.0.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "mail-counter"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rusqlite = { version = "0.37", features = ["bundled"] }
|
|
||||||
serde_json = "1"
|
|
||||||
|
|
||||||
[lints.rust]
|
|
||||||
unsafe_code = "warn"
|
|
||||||
|
|
||||||
[lints.clippy]
|
|
||||||
all = "warn"
|
|
||||||
pedantic = "warn"
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# mail-counter
|
|
||||||
|
|
||||||
Waybar custom mail module for Thunderbird. It reads Thunderbird's
|
|
||||||
`global-messages-db.sqlite` and prints JSON for Waybar.
|
|
||||||
|
|
||||||
## Build On Bazzite
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/mail-counter
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail
|
|
||||||
```
|
|
||||||
|
|
||||||
Waybar config should call the compiled binary:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
"exec": "~/.config/waybar/scripts/mail"
|
|
||||||
```
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
use std::{
|
|
||||||
env, fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use rusqlite::{Connection, OpenFlags};
|
|
||||||
use serde_json::{Value, json};
|
|
||||||
|
|
||||||
const MAIL_ICON: &str = "\u{f01ee}";
|
|
||||||
|
|
||||||
fn thunderbird_profile() -> Option<PathBuf> {
|
|
||||||
let home = PathBuf::from(env::var_os("HOME")?);
|
|
||||||
let roots = [
|
|
||||||
home.join(".var/app/org.mozilla.Thunderbird/.thunderbird"),
|
|
||||||
home.join(".thunderbird"),
|
|
||||||
];
|
|
||||||
|
|
||||||
roots.iter().find_map(|root| {
|
|
||||||
let mut profiles = fs::read_dir(root)
|
|
||||||
.ok()?
|
|
||||||
.filter_map(Result::ok)
|
|
||||||
.map(|entry| entry.path())
|
|
||||||
.filter(|path| {
|
|
||||||
path.is_dir()
|
|
||||||
&& path
|
|
||||||
.file_name()
|
|
||||||
.and_then(|name| name.to_str())
|
|
||||||
.is_some_and(|name| name.ends_with(".default-esr"))
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
profiles.sort();
|
|
||||||
profiles.into_iter().next()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn open_readonly_database(path: &Path) -> rusqlite::Result<Connection> {
|
|
||||||
Connection::open_with_flags(
|
|
||||||
path,
|
|
||||||
OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unread_from_messages(conn: &Connection) -> rusqlite::Result<i64> {
|
|
||||||
conn.query_row(
|
|
||||||
r#"SELECT COUNT(*)
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonAttributes LIKE '%"read":false%'
|
|
||||||
OR jsonAttributes LIKE '%"read": false%'"#,
|
|
||||||
[],
|
|
||||||
|row| row.get(0),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unread_from_folders(conn: &Connection) -> rusqlite::Result<i64> {
|
|
||||||
conn.query_row(
|
|
||||||
"SELECT SUM(numNewMessages) FROM folderlocations WHERE numNewMessages > 0",
|
|
||||||
[],
|
|
||||||
|row| row.get::<_, Option<i64>>(0),
|
|
||||||
)
|
|
||||||
.map(Option::unwrap_or_default)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unread_count(db_path: &Path) -> i64 {
|
|
||||||
let Ok(conn) = open_readonly_database(db_path) else {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
unread_from_messages(&conn)
|
|
||||||
.or_else(|_| unread_from_folders(&conn))
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn waybar_json(count: i64) -> Value {
|
|
||||||
if count > 0 {
|
|
||||||
json!({
|
|
||||||
"text": format!("{MAIL_ICON} {count}"),
|
|
||||||
"tooltip": format!("{count} unread emails"),
|
|
||||||
"class": "unread",
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
json!({
|
|
||||||
"text": MAIL_ICON,
|
|
||||||
"tooltip": "No unread emails",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let Some(profile) = thunderbird_profile() else {
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
json!({
|
|
||||||
"text": "",
|
|
||||||
"tooltip": "No Thunderbird profile found",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let db_path = profile.join("global-messages-db.sqlite");
|
|
||||||
if !db_path.exists() {
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
json!({
|
|
||||||
"text": "",
|
|
||||||
"tooltip": "No message database",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("{}", waybar_json(unread_count(&db_path)));
|
|
||||||
}
|
|
||||||
@@ -1,625 +0,0 @@
|
|||||||
debug {
|
|
||||||
// preview-render "screencast"
|
|
||||||
// preview-render "screen-capture"
|
|
||||||
// dbus-interfaces-in-non-session-instances
|
|
||||||
// wait-for-frame-completion-before-queueing
|
|
||||||
// enable-overlay-planes
|
|
||||||
disable-cursor-plane
|
|
||||||
// disable-direct-scanout
|
|
||||||
// render-drm-device "/dev/dri/renderD129"
|
|
||||||
// render-drm-device "/dev/dri/card1"
|
|
||||||
// enable-color-transformations-capability
|
|
||||||
// emulate-zero-presentation-time
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
keyboard {
|
|
||||||
xkb {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
repeat-delay 500
|
|
||||||
repeat-rate 30
|
|
||||||
|
|
||||||
// track-layout "window"
|
|
||||||
}
|
|
||||||
|
|
||||||
touchpad {
|
|
||||||
tap
|
|
||||||
// dwt
|
|
||||||
// dwtp
|
|
||||||
natural-scroll
|
|
||||||
accel-speed 0.4
|
|
||||||
// click-method "clickfinger"
|
|
||||||
// accel-profile "flat"
|
|
||||||
// tap-button-map "left-middle-right"
|
|
||||||
}
|
|
||||||
|
|
||||||
mouse {
|
|
||||||
// natural-scroll
|
|
||||||
// accel-speed -1.0
|
|
||||||
// accel-profile "flat"
|
|
||||||
}
|
|
||||||
|
|
||||||
tablet {
|
|
||||||
// map-to-output "eDP-1"
|
|
||||||
// map-to-output "HDMI-A-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable-power-key-handling
|
|
||||||
// warp-mouse-to-focus
|
|
||||||
// focus-follows-mouse
|
|
||||||
// workspace-auto-back-and-forth
|
|
||||||
}
|
|
||||||
|
|
||||||
output "winit" {
|
|
||||||
// scale 2.0
|
|
||||||
// scale 3.0
|
|
||||||
// transform "flipped-90"
|
|
||||||
position x=100 y=200
|
|
||||||
}
|
|
||||||
|
|
||||||
output "DP-1" {
|
|
||||||
// off
|
|
||||||
|
|
||||||
scale 1.0
|
|
||||||
// transform "90"
|
|
||||||
position x=0 y=0
|
|
||||||
// mode "1920x1200"
|
|
||||||
mode "2560x1440@170.001"
|
|
||||||
// mode "1280x1024"
|
|
||||||
// mode "1280x720"
|
|
||||||
// mode "640x480"
|
|
||||||
|
|
||||||
// variable-refresh-rate
|
|
||||||
}
|
|
||||||
|
|
||||||
layout {
|
|
||||||
focus-ring {
|
|
||||||
off
|
|
||||||
width 2
|
|
||||||
// catppuccin-mocha Sapphire
|
|
||||||
active-color "#74c7ec"
|
|
||||||
// catppuccin-mocha Surface2
|
|
||||||
inactive-color "#585b70"
|
|
||||||
|
|
||||||
// active-gradient from="#80c8ff" to="#bbddff" angle=45
|
|
||||||
}
|
|
||||||
|
|
||||||
border {
|
|
||||||
// off
|
|
||||||
width 2
|
|
||||||
// width 128
|
|
||||||
|
|
||||||
// active-color "#f38ba8"
|
|
||||||
// inactive-color "#585b70"
|
|
||||||
|
|
||||||
active-gradient from="#f38ba8" to="#f9e2af" angle=45 relative-to="workspace-view"
|
|
||||||
inactive-gradient from="#585b70" to="#7f849c" angle=45 relative-to="workspace-view"
|
|
||||||
|
|
||||||
// inactive-gradient from="green" to="lightblue" angle=45 relative-to="workspace-view"
|
|
||||||
// active-gradient from="#f00" to="#0f0" angle=90
|
|
||||||
|
|
||||||
// active-gradient from="yellow" to="red" angle=45 relative-to="workspace-view"
|
|
||||||
// inactive-gradient from="yellow" to="red" angle=45
|
|
||||||
}
|
|
||||||
|
|
||||||
preset-column-widths {
|
|
||||||
proportion 0.3333333333333333
|
|
||||||
proportion 0.5
|
|
||||||
proportion 0.66667
|
|
||||||
// proportion 0.25
|
|
||||||
// fixed 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
default-column-width { proportion 0.3333333333333333; }
|
|
||||||
// default-column-width { }
|
|
||||||
|
|
||||||
gaps 4
|
|
||||||
|
|
||||||
struts {
|
|
||||||
// left 64
|
|
||||||
// right 64
|
|
||||||
// top 44
|
|
||||||
// bottom 64
|
|
||||||
// top 64
|
|
||||||
}
|
|
||||||
|
|
||||||
// center-focused-column "on-overflow"
|
|
||||||
// center-focused-column "always"
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor {
|
|
||||||
// xcursor-theme "breeze_cursors"
|
|
||||||
// xcursor-theme "arstieonart"
|
|
||||||
// xcursor-size 48
|
|
||||||
}
|
|
||||||
|
|
||||||
prefer-no-csd
|
|
||||||
|
|
||||||
// spawn-at-startup "alacritty" "-e" "fish"
|
|
||||||
|
|
||||||
environment {
|
|
||||||
// GSK_RENDERER "cairo"
|
|
||||||
// WAYLAND_DISPLAY null
|
|
||||||
}
|
|
||||||
|
|
||||||
// screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
|
|
||||||
spawn-at-startup "sh" "-c" "exec ~/.local/bin/swaybg -i ~/Pictures/Wallpapers/image.png -m fill"
|
|
||||||
spawn-at-startup "waybar"
|
|
||||||
hotkey-overlay {
|
|
||||||
// skip-at-startup
|
|
||||||
}
|
|
||||||
|
|
||||||
animations {
|
|
||||||
// off
|
|
||||||
// slowdown 10.0
|
|
||||||
// slowdown 4.0
|
|
||||||
// slowdown 2.0
|
|
||||||
// slowdown 1.5
|
|
||||||
|
|
||||||
workspace-switch {
|
|
||||||
// off
|
|
||||||
// duration-ms 2500
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=1.0 stiffness=1000 epsilon=0.0001
|
|
||||||
}
|
|
||||||
|
|
||||||
window-open {
|
|
||||||
// off
|
|
||||||
// duration-ms 2500
|
|
||||||
// curve "ease-out-expo"
|
|
||||||
// spring damping-ratio=0.8 stiffness=1000 epsilon=0.0001
|
|
||||||
}
|
|
||||||
|
|
||||||
window-close {
|
|
||||||
// off
|
|
||||||
// duration-ms 2500
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=0.8 stiffness=1000 epsilon=0.0001
|
|
||||||
}
|
|
||||||
|
|
||||||
horizontal-view-movement {
|
|
||||||
// off
|
|
||||||
// duration-ms 500
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=1.0 stiffness=20 epsilon=0.00001
|
|
||||||
// spring damping-ratio=10.0 stiffness=800 epsilon=0.0001
|
|
||||||
}
|
|
||||||
|
|
||||||
window-movement {
|
|
||||||
// off
|
|
||||||
// duration-ms 750
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=1.0 stiffness=20 epsilon=0.00001
|
|
||||||
// spring damping-ratio=0.2 stiffness=800 epsilon=0.0001
|
|
||||||
}
|
|
||||||
|
|
||||||
window-resize {
|
|
||||||
// off
|
|
||||||
// duration-ms 500
|
|
||||||
// duration-ms 2500
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=0.2 stiffness=800 epsilon=0.0001
|
|
||||||
|
|
||||||
custom-shader r"
|
|
||||||
vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) {
|
|
||||||
vec3 coords_next_geo = niri_curr_geo_to_next_geo * coords_curr_geo;
|
|
||||||
vec3 coords_prev_geo = niri_curr_geo_to_prev_geo * coords_curr_geo;
|
|
||||||
|
|
||||||
vec3 coords_crop = niri_geo_to_tex_next * coords_next_geo;
|
|
||||||
vec3 coords_stretch = niri_geo_to_tex_next * coords_curr_geo;
|
|
||||||
vec3 coords_stretch_prev = niri_geo_to_tex_prev * coords_curr_geo;
|
|
||||||
|
|
||||||
// We can crop if the current window size is smaller than the next window
|
|
||||||
// size. One way to tell is by comparing to 1.0 the X and Y scaling
|
|
||||||
// coefficients in the current-to-next transformation matrix.
|
|
||||||
bool can_crop_by_x = niri_curr_geo_to_next_geo[0][0] <= 1.0;
|
|
||||||
bool can_crop_by_y = niri_curr_geo_to_next_geo[1][1] <= 1.0;
|
|
||||||
bool crop = can_crop_by_x && can_crop_by_y;
|
|
||||||
|
|
||||||
vec4 color;
|
|
||||||
|
|
||||||
if (crop) {
|
|
||||||
// However, when we crop, we also want to crop out anything outside the
|
|
||||||
// current geometry. This is because the area of the shader is unspecified
|
|
||||||
// and usually bigger than the current geometry, so if we don't fill pixels
|
|
||||||
// outside with transparency, the texture will leak out.
|
|
||||||
//
|
|
||||||
// When stretching, this is not an issue because the area outside will
|
|
||||||
// correspond to client-side decoration shadows, which are already supposed
|
|
||||||
// to be outside.
|
|
||||||
if (coords_curr_geo.x < 0.0 || 1.0 < coords_curr_geo.x ||
|
|
||||||
coords_curr_geo.y < 0.0 || 1.0 < coords_curr_geo.y) {
|
|
||||||
color = vec4(0.0);
|
|
||||||
} else {
|
|
||||||
color = texture2D(niri_tex_next, coords_crop.st);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we can't crop, then crossfade.
|
|
||||||
color = texture2D(niri_tex_next, coords_stretch.st);
|
|
||||||
vec4 color_prev = texture2D(niri_tex_prev, coords_stretch_prev.st);
|
|
||||||
color = mix(color_prev, color, niri_clamped_progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
}
|
|
||||||
|
|
||||||
config-notification-open-close {
|
|
||||||
// off
|
|
||||||
// duration-ms 250
|
|
||||||
// curve "ease-out-cubic"
|
|
||||||
// spring damping-ratio=0.1 stiffness=1000 epsilon=0.001
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
// match app-id="Alacritty"
|
|
||||||
// match app-id="Adwaita"
|
|
||||||
// opacity 0.9
|
|
||||||
// opacity 0.5
|
|
||||||
// opacity 0.98
|
|
||||||
|
|
||||||
// open-on-output "eDP-1"
|
|
||||||
// default-column-width { proportion 0.5; }
|
|
||||||
// default-column-width { fixed 400; }
|
|
||||||
// default-column-width {}
|
|
||||||
// open-maximized true
|
|
||||||
// open-fullscreen true
|
|
||||||
// block-out-from "screencast"
|
|
||||||
|
|
||||||
// min-width 400
|
|
||||||
// max-width 400
|
|
||||||
// min-height 400
|
|
||||||
// max-height 400
|
|
||||||
|
|
||||||
focus-ring {
|
|
||||||
// on
|
|
||||||
// active-gradient from="red" to="green"
|
|
||||||
// active-color "lightgreen"
|
|
||||||
// width 1
|
|
||||||
}
|
|
||||||
|
|
||||||
border {
|
|
||||||
// off
|
|
||||||
// on
|
|
||||||
// width 12
|
|
||||||
// width 0
|
|
||||||
// active-color "#ff808080"
|
|
||||||
// active-color "red"
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw-border-with-background true
|
|
||||||
// draw-border-with-background false
|
|
||||||
|
|
||||||
// geometry-corner-radius 12 24 32 64
|
|
||||||
// geometry-corner-radius 999
|
|
||||||
// geometry-corner-radius 1
|
|
||||||
geometry-corner-radius 6
|
|
||||||
clip-to-geometry true
|
|
||||||
}
|
|
||||||
|
|
||||||
/-window-rule {
|
|
||||||
match app-id="Adwaita"
|
|
||||||
// opacity 0.5
|
|
||||||
block-out-from "screencast"
|
|
||||||
geometry-corner-radius 12
|
|
||||||
clip-to-geometry false
|
|
||||||
border {
|
|
||||||
// off
|
|
||||||
width 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/-window-rule {
|
|
||||||
match app-id="terminal"
|
|
||||||
clip-to-geometry false
|
|
||||||
geometry-corner-radius 8 8 0 0
|
|
||||||
border {
|
|
||||||
// width 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/-window-rule {
|
|
||||||
match app-id="code"
|
|
||||||
// opacity 0.98
|
|
||||||
border {
|
|
||||||
// off
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/-window-rule {
|
|
||||||
match app-id="weston."
|
|
||||||
// block-out-from "screencast"
|
|
||||||
geometry-corner-radius 12 24 32 64
|
|
||||||
// geometry-corner-radius 999
|
|
||||||
clip-to-geometry true
|
|
||||||
}
|
|
||||||
|
|
||||||
// window-rule {
|
|
||||||
// match app-id="Alacritty"
|
|
||||||
// geometry-corner-radius 12 12 0 0
|
|
||||||
// border {
|
|
||||||
// width 2
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match title="simple-egl"
|
|
||||||
// min-width 128
|
|
||||||
// max-width 128
|
|
||||||
// min-height 128
|
|
||||||
// max-height 128
|
|
||||||
// match is-focused=true
|
|
||||||
// match is-active=false
|
|
||||||
// opacity 0.9
|
|
||||||
// block-out-from "screencast"
|
|
||||||
// block-out-from "screen-capture"
|
|
||||||
// min-width 1000
|
|
||||||
draw-border-with-background false
|
|
||||||
// match app-id="mpv"
|
|
||||||
// open-on-output "HDMI-A-1"
|
|
||||||
// open-maximized true
|
|
||||||
// default-column-width { proportion 0.5; }
|
|
||||||
// open-fullscreen false
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match title="khal-popup"
|
|
||||||
open-floating true
|
|
||||||
default-floating-position x=0 y=0 relative-to="top-right"
|
|
||||||
default-column-width { fixed 600; }
|
|
||||||
default-window-height { fixed 400; }
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match is-active=false
|
|
||||||
// opacity 0.95
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^org\.telegram\.desktop$"# title="^Media viewer$"
|
|
||||||
open-fullscreen false
|
|
||||||
default-column-width { proportion 0.5; }
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^org\.wezfurlong\.wezterm$"#
|
|
||||||
match app-id="^mpv$"
|
|
||||||
default-column-width {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Qt used by OBS doesn't signal min size yet, so do it manually.
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^com\.obsproject\.Studio$"#
|
|
||||||
min-width 876
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id="^blender$"
|
|
||||||
match app-id="^gimp"
|
|
||||||
default-column-width { fixed 1200; }
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id="^obsidian$"
|
|
||||||
default-column-width { fixed 1000; }
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"#
|
|
||||||
match app-id=r#"^org\.telegram\.desktop$"#
|
|
||||||
exclude app-id=r#"^org\.telegram\.desktop$"# title="^Media viewer$"
|
|
||||||
|
|
||||||
open-on-output "DP-2"
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"#
|
|
||||||
|
|
||||||
default-column-width { proportion 0.66667; }
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
|
|
||||||
match app-id=r#"^org\.gnome\.World\.Secrets$"#
|
|
||||||
match app-id=r#"^org\.telegram\.desktop$"#
|
|
||||||
|
|
||||||
// Doesn't quite work: Firefox changes the title one frame early.
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title="- Gmail "
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title="^Google Calendar "
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title="Todoist "
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title=r#"^GNOME( \*)? \| "#
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title=r#"^Element "#
|
|
||||||
match app-id=r#"^org\.mozilla\.firefox$"# title=r#"Discord \| "#
|
|
||||||
|
|
||||||
block-out-from "screencast"
|
|
||||||
// block-out-from "screen-capture"
|
|
||||||
|
|
||||||
border {
|
|
||||||
// active-color "red"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binds {
|
|
||||||
Mod+Shift+Slash { show-hotkey-overlay; }
|
|
||||||
|
|
||||||
Mod+Shift+C { spawn "sh" "-c" "t env DISPLAY=:0 xsel -ob | wl-copy"; }
|
|
||||||
Mod+Shift+V { spawn "sh" "-c" "wl-paste -n | t env DISPLAY=:0 xsel -ib"; }
|
|
||||||
|
|
||||||
// Mod+T { spawn "sh" "-c" "alacritty msg create-window -e fish -C t || alacritty -e fish -C t"; }
|
|
||||||
Mod+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; }
|
|
||||||
Mod+Shift+T { spawn "alacritty"; }
|
|
||||||
// Mod+Shift+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; }
|
|
||||||
// Mod+Return { spawn "~/arst"; }
|
|
||||||
// Mod+T { spawn "flatpak" "run" "org.gnome.Ptyxis.Devel" "-s"; }
|
|
||||||
// Mod+T { spawn "~/.local/bin/spawn-ptyxis.sh"; }
|
|
||||||
// Mod+T { spawn "bash" "-c" "notify-send hello && exec alacritty"; }
|
|
||||||
// Mod+T { spawn "kgx" "-e" "fish -C t"; }
|
|
||||||
Mod+D { spawn "fuzzel"; }
|
|
||||||
Mod+H { spawn "nautilus"; }
|
|
||||||
Super+Alt+L allow-when-locked=true { spawn "swaylock"; }
|
|
||||||
|
|
||||||
Mod+W { spawn "sh" "-c" "t mpv --pause $(wl-paste)"; }
|
|
||||||
Super+Alt+H { spawn "refresh.sh" "144"; }
|
|
||||||
Super+Alt+Comma { spawn "refresh.sh" "120"; }
|
|
||||||
|
|
||||||
XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"; }
|
|
||||||
XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"; }
|
|
||||||
XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
|
||||||
XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
|
|
||||||
|
|
||||||
Mod+Q { close-window; }
|
|
||||||
Mod+BackSpace { close-window; }
|
|
||||||
|
|
||||||
Mod+M { focus-column-left; }
|
|
||||||
Mod+N { focus-window-down; }
|
|
||||||
Mod+E { focus-window-up; }
|
|
||||||
Mod+I { focus-column-right; }
|
|
||||||
Mod+Left { focus-column-left; }
|
|
||||||
Mod+Down { focus-window-down; }
|
|
||||||
Mod+Up { focus-window-up; }
|
|
||||||
Mod+Right { focus-column-right; }
|
|
||||||
|
|
||||||
Mod+Ctrl+M { move-column-left; }
|
|
||||||
Mod+Ctrl+N { move-window-down; }
|
|
||||||
Mod+Ctrl+E { move-window-up; }
|
|
||||||
Mod+Ctrl+I { move-column-right; }
|
|
||||||
Mod+Ctrl+Left { move-column-left; }
|
|
||||||
Mod+Ctrl+Down { move-window-down; }
|
|
||||||
Mod+Ctrl+Up { move-window-up; }
|
|
||||||
Mod+Ctrl+Right { move-column-right; }
|
|
||||||
|
|
||||||
Mod+Home { focus-column-first; }
|
|
||||||
Mod+End { focus-column-last; }
|
|
||||||
Mod+Ctrl+Home { move-column-to-first; }
|
|
||||||
Mod+Ctrl+End { move-column-to-last; }
|
|
||||||
|
|
||||||
Mod+Shift+M { focus-monitor-left; }
|
|
||||||
Mod+Shift+N { focus-monitor-down; }
|
|
||||||
Mod+Shift+E { focus-monitor-up; }
|
|
||||||
Mod+Shift+I { focus-monitor-right; }
|
|
||||||
Mod+Shift+Left { focus-monitor-left; }
|
|
||||||
Mod+Shift+Down { focus-monitor-down; }
|
|
||||||
Mod+Shift+Up { focus-monitor-up; }
|
|
||||||
Mod+Shift+Right { focus-monitor-right; }
|
|
||||||
|
|
||||||
Mod+Shift+Ctrl+M { move-column-to-monitor-left; }
|
|
||||||
Mod+Shift+Ctrl+N { move-column-to-monitor-down; }
|
|
||||||
Mod+Shift+Ctrl+E { move-column-to-monitor-up; }
|
|
||||||
Mod+Shift+Ctrl+I { move-column-to-monitor-right; }
|
|
||||||
Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
|
|
||||||
Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
|
|
||||||
Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
|
|
||||||
Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
|
|
||||||
|
|
||||||
Mod+Shift+Alt+M { move-workspace-to-monitor-left; }
|
|
||||||
Mod+Shift+Alt+N { move-workspace-to-monitor-down; }
|
|
||||||
Mod+Shift+Alt+E { move-workspace-to-monitor-up; }
|
|
||||||
Mod+Shift+Alt+I { move-workspace-to-monitor-right; }
|
|
||||||
Mod+Shift+Alt+Left { move-workspace-to-monitor-left; }
|
|
||||||
Mod+Shift+Alt+Down { move-workspace-to-monitor-down; }
|
|
||||||
Mod+Shift+Alt+Up { move-workspace-to-monitor-up; }
|
|
||||||
Mod+Shift+Alt+Right { move-workspace-to-monitor-right; }
|
|
||||||
|
|
||||||
Mod+L { focus-workspace-down; }
|
|
||||||
Mod+U { focus-workspace-up; }
|
|
||||||
Mod+Page_Down { focus-workspace-down; }
|
|
||||||
Mod+Page_Up { focus-workspace-up; }
|
|
||||||
Mod+Ctrl+L { move-column-to-workspace-down; }
|
|
||||||
Mod+Ctrl+U { move-column-to-workspace-up; }
|
|
||||||
Mod+Ctrl+Page_Down { move-column-to-workspace-down; }
|
|
||||||
Mod+Ctrl+Page_Up { move-column-to-workspace-up; }
|
|
||||||
|
|
||||||
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
|
||||||
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
|
||||||
Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
|
||||||
Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
|
||||||
|
|
||||||
Mod+WheelScrollRight { focus-column-right; }
|
|
||||||
Mod+WheelScrollLeft { focus-column-left; }
|
|
||||||
Mod+Ctrl+WheelScrollRight { move-column-right; }
|
|
||||||
Mod+Ctrl+WheelScrollLeft { move-column-left; }
|
|
||||||
|
|
||||||
Mod+Shift+WheelScrollDown { focus-column-right; }
|
|
||||||
Mod+Shift+WheelScrollUp { focus-column-left; }
|
|
||||||
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
|
|
||||||
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
|
|
||||||
|
|
||||||
Mod+TouchpadScrollUp allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
|
|
||||||
Mod+TouchpadScrollDown allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
|
|
||||||
// Mod+TouchpadScrollLeft { focus-column-left; }
|
|
||||||
// Mod+TouchpadScrollRight { focus-column-right; }
|
|
||||||
|
|
||||||
Mod+Shift+L { move-workspace-down; }
|
|
||||||
Mod+Shift+U { move-workspace-up; }
|
|
||||||
Mod+Shift+Page_Down { move-workspace-down; }
|
|
||||||
Mod+Shift+Page_Up { move-workspace-up; }
|
|
||||||
|
|
||||||
Mod+1 { focus-workspace 1; }
|
|
||||||
Mod+2 { focus-workspace 2; }
|
|
||||||
Mod+3 { focus-workspace 3; }
|
|
||||||
Mod+4 { focus-workspace 4; }
|
|
||||||
Mod+5 { focus-workspace 5; }
|
|
||||||
Mod+6 { focus-workspace 6; }
|
|
||||||
Mod+7 { focus-workspace 7; }
|
|
||||||
Mod+8 { focus-workspace 8; }
|
|
||||||
Mod+9 { focus-workspace 9; }
|
|
||||||
Mod+Ctrl+1 { move-column-to-workspace 1; }
|
|
||||||
Mod+Ctrl+2 { move-column-to-workspace 2; }
|
|
||||||
Mod+Ctrl+3 { move-column-to-workspace 3; }
|
|
||||||
Mod+Ctrl+4 { move-column-to-workspace 4; }
|
|
||||||
Mod+Ctrl+5 { move-column-to-workspace 5; }
|
|
||||||
Mod+Ctrl+6 { move-column-to-workspace 6; }
|
|
||||||
Mod+Ctrl+7 { move-column-to-workspace 7; }
|
|
||||||
Mod+Ctrl+8 { move-column-to-workspace 8; }
|
|
||||||
Mod+Ctrl+9 { move-column-to-workspace 9; }
|
|
||||||
|
|
||||||
// Mod+Tab { focus-workspace-previous; }
|
|
||||||
|
|
||||||
Mod+Comma { consume-window-into-column; }
|
|
||||||
Mod+Period { expel-window-from-column; }
|
|
||||||
|
|
||||||
Mod+BracketLeft { consume-or-expel-window-left; }
|
|
||||||
Mod+BracketRight { consume-or-expel-window-right; }
|
|
||||||
|
|
||||||
Mod+R { switch-preset-column-width; }
|
|
||||||
Mod+F { maximize-column; }
|
|
||||||
Mod+Shift+F { fullscreen-window; }
|
|
||||||
Mod+C { center-column; }
|
|
||||||
|
|
||||||
Mod+Minus { set-column-width "-10%"; }
|
|
||||||
Mod+Equal { set-column-width "+10%"; }
|
|
||||||
Mod+Ctrl+Minus { set-column-width "-1"; }
|
|
||||||
Mod+Ctrl+Equal { set-column-width "+1"; }
|
|
||||||
|
|
||||||
Mod+Shift+Minus { set-window-height "-10%"; }
|
|
||||||
Mod+Shift+Equal { set-window-height "+10%"; }
|
|
||||||
Mod+Shift+Ctrl+Minus { set-window-height "-1"; }
|
|
||||||
Mod+Shift+Ctrl+Equal { set-window-height "+1"; }
|
|
||||||
|
|
||||||
Mod+0 { set-column-width "960"; }
|
|
||||||
Mod+Shift+0 { set-window-height "540"; }
|
|
||||||
Mod+Alt+0 { set-column-width "1280"; }
|
|
||||||
Mod+Shift+Alt+0 { set-window-height "720"; }
|
|
||||||
Mod+Ctrl+0 { set-column-width "1920"; }
|
|
||||||
Mod+Shift+Ctrl+0 { set-window-height "1080"; }
|
|
||||||
|
|
||||||
Mod+Space { switch-layout "next"; }
|
|
||||||
Mod+Shift+Space { switch-layout "prev"; }
|
|
||||||
|
|
||||||
Print { screenshot; }
|
|
||||||
Ctrl+Print { screenshot-screen; }
|
|
||||||
Alt+Print { screenshot-window; }
|
|
||||||
|
|
||||||
Mod+P { screenshot; }
|
|
||||||
|
|
||||||
Mod+Shift+Y { quit; }
|
|
||||||
Mod+Shift+P { power-off-monitors; }
|
|
||||||
|
|
||||||
Mod+Shift+Ctrl+T { toggle-debug-tint; }
|
|
||||||
Mod+Shift+Ctrl+O { debug-toggle-opaque-regions; }
|
|
||||||
Mod+Shift+Ctrl+D { debug-toggle-damage; }
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 5.0 MiB |
|
Before Width: | Height: | Size: 804 KiB |
@@ -1,179 +0,0 @@
|
|||||||
// -*- mode: jsonc -*-
|
|
||||||
{
|
|
||||||
"layer": "top",
|
|
||||||
"height": 32,
|
|
||||||
"spacing": 8,
|
|
||||||
|
|
||||||
"modules-left": [
|
|
||||||
"niri/workspaces"
|
|
||||||
],
|
|
||||||
"modules-center": [
|
|
||||||
"niri/window"
|
|
||||||
],
|
|
||||||
"modules-right": [
|
|
||||||
"privacy",
|
|
||||||
"custom/mail",
|
|
||||||
"custom/weather",
|
|
||||||
"pulseaudio",
|
|
||||||
"network",
|
|
||||||
"niri/language",
|
|
||||||
"power-profiles-daemon",
|
|
||||||
"cpu",
|
|
||||||
"memory",
|
|
||||||
"temperature",
|
|
||||||
"custom/gpu",
|
|
||||||
"disk",
|
|
||||||
"custom/calendar",
|
|
||||||
"tray"
|
|
||||||
],
|
|
||||||
|
|
||||||
"niri/workspaces": {
|
|
||||||
"format": "{index}"
|
|
||||||
},
|
|
||||||
|
|
||||||
"niri/window": {
|
|
||||||
"format": "{}",
|
|
||||||
"max-length": 50,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"niri/language": {
|
|
||||||
"format": "{short}",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"privacy": {
|
|
||||||
"icon-spacing": 4,
|
|
||||||
"icon-size": 16,
|
|
||||||
"transition-duration": 250,
|
|
||||||
"modules": [
|
|
||||||
{ "type": "screenshare" },
|
|
||||||
{ "type": "audio-in" },
|
|
||||||
{ "type": "audio-out" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/mail": {
|
|
||||||
"format": "<span font='Symbols Nerd Font Mono'>{}</span>",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/mail",
|
|
||||||
"interval": 60,
|
|
||||||
"tooltip": true,
|
|
||||||
"on-click": "flatpak run org.mozilla.Thunderbird",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/weather": {
|
|
||||||
"format": "{}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/weather.sh",
|
|
||||||
"interval": 900,
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/gpu": {
|
|
||||||
"format": "{}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/gpu.sh",
|
|
||||||
"interval": 5,
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free'></span> {percentage_used}%",
|
|
||||||
"path": "/",
|
|
||||||
"tooltip-format": "{used} / {total} ({percentage_used}%)",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"tray": {
|
|
||||||
"spacing": 10
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/calendar": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free'></span> {}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/khal-calendar",
|
|
||||||
"interval": 30,
|
|
||||||
"tooltip": true,
|
|
||||||
"on-click": "alacritty --title khal-popup -e bash -c 'vdirsyncer sync 2>/dev/null; ikhal'",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {usage}%",
|
|
||||||
"tooltip": false,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"memory": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {}%",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"temperature": {
|
|
||||||
"critical-threshold": 80,
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {temperatureC}°C",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"network": {
|
|
||||||
"format-wifi": "<span font='Symbols Nerd Font Mono'>{icon}</span>",
|
|
||||||
"format-ethernet": "",
|
|
||||||
"format-icons": ["", "", "", "", ""],
|
|
||||||
"tooltip-format-wifi": "{essid} ({signalStrength}%)\n{ipaddr}/{cidr}",
|
|
||||||
"tooltip-format-ethernet": "{ifname}\n{ipaddr}/{cidr}",
|
|
||||||
"format-linked": "{ifname} (No IP) ",
|
|
||||||
"format-disconnected": "<span font='Symbols Nerd Font Mono'></span>",
|
|
||||||
"on-click": "",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"pulseaudio": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'>{icon}</span> {volume}% <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-bluetooth": "<span font='Font Awesome 6 Free Solid'>{icon}</span> {volume}% <span font='Font Awesome 6 Brands'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-bluetooth-muted": "<span font='Font Awesome 6 Free Solid'></span> <span font='Font Awesome 6 Brands'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-muted": "<span font='Font Awesome 6 Free Solid'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-source": "{volume}%",
|
|
||||||
"format-source-muted": "<span font='Font Awesome 6 Free Solid'></span>",
|
|
||||||
"format-icons": {
|
|
||||||
"headphone": "",
|
|
||||||
"hands-free": "",
|
|
||||||
"headset": "",
|
|
||||||
"phone": "",
|
|
||||||
"portable": "",
|
|
||||||
"car": "",
|
|
||||||
"default": ["", "", ""]
|
|
||||||
},
|
|
||||||
"on-click": "pavucontrol",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"power-profiles-daemon": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'>{icon}</span>",
|
|
||||||
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center",
|
|
||||||
"format-icons": {
|
|
||||||
"default": "",
|
|
||||||
"performance": "",
|
|
||||||
"balanced": "",
|
|
||||||
"power-saver": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
|
|
||||||
if [ -z "$data" ]; then
|
|
||||||
echo '{"text": "GPU N/A", "tooltip": "nvidia-smi not available"}'
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
usage=$(echo "$data" | cut -d',' -f1 | tr -d ' ')
|
|
||||||
temp=$(echo "$data" | cut -d',' -f2 | tr -d ' ')
|
|
||||||
echo "{\"text\": \"GPU ${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
weather=$(curl -s "wttr.in/?format=%c%t" 2>/dev/null)
|
|
||||||
if [ -z "$weather" ] || echo "$weather" | grep -q "Unknown"; then
|
|
||||||
echo '{"text": "N/A", "tooltip": "Weather unavailable"}'
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
tooltip=$(curl -s "wttr.in/?format=%l:+%C+%t+%w+%h" 2>/dev/null)
|
|
||||||
echo "{\"text\": \"${weather}\", \"tooltip\": \"${tooltip}\"}"
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
/* Catppuccin Latte */
|
|
||||||
@define-color rosewater #dc8a78;
|
|
||||||
@define-color flamingo #dd7878;
|
|
||||||
@define-color pink #ea76cb;
|
|
||||||
@define-color mauve #8839ef;
|
|
||||||
@define-color red #d20f39;
|
|
||||||
@define-color maroon #e64553;
|
|
||||||
@define-color peach #fe640b;
|
|
||||||
@define-color yellow #df8e1d;
|
|
||||||
@define-color green #40a02b;
|
|
||||||
@define-color teal #179299;
|
|
||||||
@define-color sky #04a5e5;
|
|
||||||
@define-color sapphire #209fb5;
|
|
||||||
@define-color blue #1e66f5;
|
|
||||||
@define-color lavender #7287fd;
|
|
||||||
@define-color text #4c4f69;
|
|
||||||
@define-color subtext1 #5c5f77;
|
|
||||||
@define-color subtext0 #6c6f85;
|
|
||||||
@define-color overlay2 #7c7f93;
|
|
||||||
@define-color overlay1 #8c8fa1;
|
|
||||||
@define-color overlay0 #9ca0b0;
|
|
||||||
@define-color surface2 #acb0be;
|
|
||||||
@define-color surface1 #bcc0cc;
|
|
||||||
@define-color surface0 #ccd0da;
|
|
||||||
@define-color base #eff1f5;
|
|
||||||
@define-color mantle #e6e9ef;
|
|
||||||
@define-color crust #dce0e8;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-family: 'Noto Sans Mono', 'Symbols Nerd Font Mono', 'Symbols Nerd Font', 'Font Awesome 6 Free', monospace;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background-color: rgba(30, 30, 46, 0.72);
|
|
||||||
color: @text;
|
|
||||||
transition-property: background-color;
|
|
||||||
transition-duration: .5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.hidden {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
box-shadow: inset 0 -3px transparent;
|
|
||||||
border: none;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background: inherit;
|
|
||||||
box-shadow: inset 0 -2px @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Workspaces */
|
|
||||||
#workspaces button {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background-color: #000000;
|
|
||||||
color: @overlay2;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button:hover {
|
|
||||||
background: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.active {
|
|
||||||
color: @blue;
|
|
||||||
box-shadow: inset 0 -2px @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.urgent {
|
|
||||||
background-color: #000000;
|
|
||||||
color: @base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Common module styling */
|
|
||||||
#window,
|
|
||||||
#custom-calendar,
|
|
||||||
#cpu,
|
|
||||||
#memory,
|
|
||||||
#disk,
|
|
||||||
#temperature,
|
|
||||||
#network,
|
|
||||||
#pulseaudio,
|
|
||||||
#wireplumber,
|
|
||||||
#tray,
|
|
||||||
#power-profiles-daemon,
|
|
||||||
#language,
|
|
||||||
#custom-gpu,
|
|
||||||
#custom-weather,
|
|
||||||
#privacy {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background-color: #000000;
|
|
||||||
border-radius: 16px;
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button label,
|
|
||||||
#window label,
|
|
||||||
#custom-calendar label,
|
|
||||||
#cpu label,
|
|
||||||
#memory label,
|
|
||||||
#disk label,
|
|
||||||
#temperature label,
|
|
||||||
#network label,
|
|
||||||
#pulseaudio label,
|
|
||||||
#wireplumber label,
|
|
||||||
#tray label,
|
|
||||||
#power-profiles-daemon label,
|
|
||||||
#language label,
|
|
||||||
#custom-gpu label,
|
|
||||||
#custom-weather label,
|
|
||||||
#privacy label {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#window,
|
|
||||||
#workspaces {
|
|
||||||
margin: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#window {
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calendar/Clock */
|
|
||||||
#custom-calendar {
|
|
||||||
color: @blue;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CPU */
|
|
||||||
#cpu {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory */
|
|
||||||
#memory {
|
|
||||||
color: @mauve;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Temperature */
|
|
||||||
#temperature {
|
|
||||||
color: @peach;
|
|
||||||
}
|
|
||||||
|
|
||||||
#temperature.critical {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Network */
|
|
||||||
#network {
|
|
||||||
color: @sapphire;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#network.disconnected {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pulseaudio */
|
|
||||||
#pulseaudio {
|
|
||||||
color: @yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio.muted {
|
|
||||||
color: @overlay1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Language */
|
|
||||||
#language {
|
|
||||||
color: @teal;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Power profiles */
|
|
||||||
#power-profiles-daemon {
|
|
||||||
color: @subtext0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.performance {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.balanced {
|
|
||||||
color: @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.power-saver {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mail */
|
|
||||||
#custom-mail {
|
|
||||||
color: @lavender;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-mail.unread {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disk */
|
|
||||||
#disk {
|
|
||||||
color: @flamingo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GPU */
|
|
||||||
#custom-gpu {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Weather */
|
|
||||||
#custom-weather {
|
|
||||||
color: @sky;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Privacy */
|
|
||||||
#privacy {
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
color: @base;
|
|
||||||
background-color: #000000;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.screenshare {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.audio-in {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.audio-out {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tray */
|
|
||||||
#tray {
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray > .passive {
|
|
||||||
-gtk-icon-effect: dim;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray > .needs-attention {
|
|
||||||
-gtk-icon-effect: highlight;
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
Gdk/UnscaledDPI 98304
|
|
||||||
Gdk/WindowScalingFactor 1
|
|
||||||
Gtk/EnableAnimations 1
|
|
||||||
Gtk/DecorationLayout "icon:minimize,maximize,close"
|
|
||||||
Net/ThemeName ""
|
|
||||||
Gtk/PrimaryButtonWarpsSlider 1
|
|
||||||
Gtk/ToolbarStyle 3
|
|
||||||
Gtk/MenuImages 1
|
|
||||||
Gtk/ButtonImages 1
|
|
||||||
Net/CursorBlinkTime 1000
|
|
||||||
Net/CursorBlink 1
|
|
||||||
Gtk/CursorThemeSize 24
|
|
||||||
Gtk/CursorThemeName "breeze_cursors"
|
|
||||||
Net/SoundThemeName "ocean"
|
|
||||||
Net/IconThemeName "breeze"
|
|
||||||
Gtk/FontName "Noto Sans, 10"
|
|
||||||
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
# Конфиги рабочего стола Fedora
|
|
||||||
|
|
||||||
Эта папка содержит профиль Fedora KDE/Workstation, где основной рабочей
|
|
||||||
Wayland-сессией становится Niri. Профиль получен из старого `bazzite/`, но
|
|
||||||
адаптирован под обычную mutable Fedora: пакеты ставятся через `dnf`, Steam
|
|
||||||
запускается обычным `/usr/bin/steam`, а локальные Bazzite helpers не требуются.
|
|
||||||
|
|
||||||
## Что здесь настроено
|
|
||||||
|
|
||||||
| Путь | Назначение |
|
|
||||||
|---|---|
|
|
||||||
| `niri/config.kdl` | Конфиг Niri: монитор `DP-1`, ввод, раскладка окон, автозапуск, правила окон, хоткеи. |
|
|
||||||
| `waybar/` | Верхняя панель: конфиг, CSS в стиле Catppuccin и custom-модули. |
|
|
||||||
| `waybar/scripts/gpu.sh` | Модуль Waybar для загрузки и температуры NVIDIA GPU через `nvidia-smi`. |
|
|
||||||
| `waybar/scripts/weather.sh` | Модуль Waybar с погодой через `wttr.in`. |
|
|
||||||
| `khal-calendar/` | Rust-версия календарного модуля Waybar. |
|
|
||||||
| `mail-counter/` | Rust-модуль Waybar для счетчика непрочитанных писем Thunderbird. |
|
|
||||||
| `calendar-mail-popup-notes.md` | Набросок UX и архитектуры для собственного calendar/mail popup из Waybar. |
|
|
||||||
| `fuzzel/fuzzel.ini` | Тема лаунчера Fuzzel на цветах Catppuccin Latte. |
|
|
||||||
| `btop/btop.conf` | Настройки системного монитора btop. |
|
|
||||||
| `glow/glow.yml` | Настройки терминального Markdown-viewer Glow. |
|
|
||||||
| `gtk-3.0/`, `gtk-4.0/` | GTK-настройки и цветовые файлы Breeze/Catppuccin. |
|
|
||||||
| `xsettingsd/xsettingsd.conf` | Настройки GTK, курсора, иконок, шрифта и DPI для X11/XWayland-приложений. |
|
|
||||||
| `environment.d/intel-gtk-fix.conf` | Переменная окружения сессии: `GSK_RENDERER=gl`. |
|
|
||||||
| `autostart/steam.desktop` | Автозапуск Steam через обычный Fedora Steam. |
|
|
||||||
| `wallpapers/raspberry.png` | Текущая картинка рабочего стола для `swaybg`. |
|
|
||||||
|
|
||||||
## Ожидаемые программы
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo dnf install -y \
|
|
||||||
niri waybar fuzzel alacritty swaybg swaylock \
|
|
||||||
btop glow xsettingsd pavucontrol xsel mpv nautilus \
|
|
||||||
khal vdirsyncer thunderbird rustup cargo
|
|
||||||
```
|
|
||||||
|
|
||||||
Также ожидается уже настроенный NVIDIA-драйвер с рабочим `nvidia-smi`.
|
|
||||||
|
|
||||||
## Установка
|
|
||||||
|
|
||||||
Подключить директории в `~/.config`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do
|
|
||||||
ln -sfn ~/dotfiles/fedora/$dir ~/.config/$dir
|
|
||||||
done
|
|
||||||
mkdir -p ~/Pictures/Wallpapers
|
|
||||||
ln -sfn ~/dotfiles/fedora/wallpapers/raspberry.png ~/Pictures/Wallpapers/raspberry.png
|
|
||||||
```
|
|
||||||
|
|
||||||
Если репозиторий лежит не в `~/dotfiles`, путь нужно поправить.
|
|
||||||
|
|
||||||
## Сборка календарного модуля
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/fedora/khal-calendar
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar
|
|
||||||
```
|
|
||||||
|
|
||||||
## Сборка почтового модуля
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/fedora/mail-counter
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail
|
|
||||||
```
|
|
||||||
|
|
||||||
Модуль читает `global-messages-db.sqlite` из профиля Thunderbird и печатает JSON
|
|
||||||
для `custom/mail` в Waybar.
|
|
||||||
|
|
||||||
## Fedora-specific отличия от Bazzite
|
|
||||||
|
|
||||||
- Steam запускается через `/usr/bin/steam`, не через `/usr/bin/bazzite-steam`.
|
|
||||||
- Wallpaper запускается через `swaybg` из `$PATH`, не через `~/.local/bin/swaybg`.
|
|
||||||
- Hotkeys на `refresh.sh` отключены, потому что этого локального helper пока нет.
|
|
||||||
- Clipboard hotkeys больше не зависят от локальной команды `t`.
|
|
||||||
- Firefox/Telegram правила Niri отправляют окна на `DP-1`, текущий подключенный
|
|
||||||
выход на этой Fedora-машине.
|
|
||||||
|
|
||||||
## Перезагрузка
|
|
||||||
|
|
||||||
После изменения конфига или CSS Waybar:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pkill -SIGUSR2 waybar
|
|
||||||
```
|
|
||||||
|
|
||||||
Если Waybar не подхватил изменения, нужно перезапустить Waybar вручную или
|
|
||||||
перезапустить Niri-сессию.
|
|
||||||
6
fedora/alacritty/alacritty.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[window]
|
||||||
|
# Let the wallpaper show through without making terminal text hard to read.
|
||||||
|
opacity = 0.8
|
||||||
|
|
||||||
|
[font]
|
||||||
|
normal = { family = "JetBrainsMono Nerd Font Mono" }
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
# Calendar + Mail Popup Notes
|
|
||||||
|
|
||||||
Заметка по идее компактного календарно-почтового инструмента для Fedora + Niri +
|
|
||||||
Waybar.
|
|
||||||
|
|
||||||
## Цель
|
|
||||||
|
|
||||||
Нужны две связанные поверхности:
|
|
||||||
|
|
||||||
1. Понятное решение в `waybar`, откуда можно быстро открыть календарь и увидеть
|
|
||||||
нужную информацию.
|
|
||||||
2. Отдельное компактное `tool-window` / popup-окно с календарем и мини-почтой.
|
|
||||||
|
|
||||||
Это не должен быть полноценный тяжелый PIM-комбайн на первом этапе. Основной
|
|
||||||
приоритет — быстрый обзор и быстрые действия.
|
|
||||||
|
|
||||||
## Что нужно уметь
|
|
||||||
|
|
||||||
### В Waybar
|
|
||||||
|
|
||||||
- Кликнуть по модулю.
|
|
||||||
- Увидеть календарную информацию без переключения в большой клиент.
|
|
||||||
- Быстро понять:
|
|
||||||
- что сегодня;
|
|
||||||
- что дальше по неделе;
|
|
||||||
- есть ли ближайшие события;
|
|
||||||
- есть ли непрочитанная почта.
|
|
||||||
|
|
||||||
### В popup/tool-window
|
|
||||||
|
|
||||||
- Посмотреть календарь на неделю и месяц.
|
|
||||||
- Увидеть список ближайших событий.
|
|
||||||
- Создать событие.
|
|
||||||
- Иметь мини-почту как обзор, а не как полноценный mail client.
|
|
||||||
|
|
||||||
## Ограничения текущего Waybar
|
|
||||||
|
|
||||||
Встроенный `clock` модуль Waybar умеет:
|
|
||||||
|
|
||||||
- показывать месяц/год;
|
|
||||||
- переключать режимы;
|
|
||||||
- листать календарь;
|
|
||||||
- запускать команды по клику.
|
|
||||||
|
|
||||||
Но встроенный календарь Waybar — только display layer:
|
|
||||||
|
|
||||||
- он не показывает реальные CalDAV / Nextcloud / Google события;
|
|
||||||
- он не умеет создавать события;
|
|
||||||
- он не является полноценным event-aware календарем.
|
|
||||||
|
|
||||||
Следствие: Waybar должен быть entry point, а не местом, где живет вся
|
|
||||||
календарная логика.
|
|
||||||
|
|
||||||
## Вывод по архитектуре
|
|
||||||
|
|
||||||
Нужна связка из двух частей:
|
|
||||||
|
|
||||||
1. `waybar` как обзор и кнопка входа;
|
|
||||||
2. отдельное маленькое приложение/окно как рабочая поверхность.
|
|
||||||
|
|
||||||
Рекомендованный подход:
|
|
||||||
|
|
||||||
- hover в `waybar` показывает компактный календарный overview;
|
|
||||||
- click открывает собственный popup/tool-window;
|
|
||||||
- popup уже работает с реальными данными календаря и почты.
|
|
||||||
|
|
||||||
## Предлагаемый UX
|
|
||||||
|
|
||||||
### 1. Waybar popover / overview
|
|
||||||
|
|
||||||
Минимальный состав:
|
|
||||||
|
|
||||||
- верх: дата, `Today`, кнопка `+ Event`;
|
|
||||||
- слева: мини-месяц;
|
|
||||||
- справа или снизу: блок `Today / Tomorrow / This Week`;
|
|
||||||
- отдельный короткий блок `Unread mail`.
|
|
||||||
|
|
||||||
Роль этого слоя:
|
|
||||||
|
|
||||||
- быстрое чтение;
|
|
||||||
- быстрый переход;
|
|
||||||
- минимум действий;
|
|
||||||
- без тяжелой навигации.
|
|
||||||
|
|
||||||
### 2. Tool-window / popup
|
|
||||||
|
|
||||||
Форма окна:
|
|
||||||
|
|
||||||
- не полноценное большое desktop app окно;
|
|
||||||
- не полноразмерный почтовый клиент;
|
|
||||||
- компактное floating window, открываемое по клику из `waybar`.
|
|
||||||
|
|
||||||
Предпочтительная компоновка:
|
|
||||||
|
|
||||||
- левая колонка: мини-месяц + список календарей;
|
|
||||||
- центральная зона: week view или month-agenda;
|
|
||||||
- правая колонка: `Upcoming`, `Reminders`, `Unread mail`.
|
|
||||||
|
|
||||||
Верхняя строка:
|
|
||||||
|
|
||||||
- `Today`
|
|
||||||
- `New event`
|
|
||||||
- `Search`
|
|
||||||
- переключение `Week / Month`
|
|
||||||
|
|
||||||
## Мини-почта: что это значит
|
|
||||||
|
|
||||||
Почта в этом окне должна быть не отдельным MUA, а summary layer:
|
|
||||||
|
|
||||||
- unread messages;
|
|
||||||
- flagged / important;
|
|
||||||
- письма за сегодня;
|
|
||||||
- клик по письму открывает внешний клиент.
|
|
||||||
|
|
||||||
Нежелательно на первом этапе:
|
|
||||||
|
|
||||||
- полноценный composing;
|
|
||||||
- threading;
|
|
||||||
- archive/reply прямо в popup;
|
|
||||||
- попытка заменить Thunderbird или другой почтовик.
|
|
||||||
|
|
||||||
Идея: calendar-first окно с mail summary, а не равноправный split mail/calendar
|
|
||||||
комбайн.
|
|
||||||
|
|
||||||
## Референсы по форме и UX
|
|
||||||
|
|
||||||
### Основной референс по форме
|
|
||||||
|
|
||||||
`Fantastical Mini Window`
|
|
||||||
|
|
||||||
- маленькое окно поверх рабочего контекста;
|
|
||||||
- быстрый обзор событий;
|
|
||||||
- быстрый add/search;
|
|
||||||
- ощущается как utility window, а не как полноразмерное приложение.
|
|
||||||
|
|
||||||
Ссылка:
|
|
||||||
|
|
||||||
- https://flexibits.com/blog/2022/04/mini-window-big-productivity-getting-the-most-from-fantastical-for-macs-mini-window/
|
|
||||||
|
|
||||||
### Референс по базовым календарным экранам
|
|
||||||
|
|
||||||
`GNOME Calendar`
|
|
||||||
|
|
||||||
- чистый month/week view;
|
|
||||||
- отдельный event editor;
|
|
||||||
- понятная структура desktop calendar без перегруза.
|
|
||||||
|
|
||||||
Ссылка:
|
|
||||||
|
|
||||||
- https://apps.gnome.org/Calendar/
|
|
||||||
|
|
||||||
### Референс по плотной рабочей компоновке
|
|
||||||
|
|
||||||
`Notion Calendar`
|
|
||||||
|
|
||||||
- маленький месяц + основной agenda/week layout;
|
|
||||||
- показывает, как совместить overview и рабочую область.
|
|
||||||
|
|
||||||
Ссылка:
|
|
||||||
|
|
||||||
- https://habr.com/ru/news/787144/
|
|
||||||
|
|
||||||
### Референс по идее mail+calendar продукта
|
|
||||||
|
|
||||||
`Thunderbird`
|
|
||||||
|
|
||||||
- полезен не как popup reference, а как пример того, что почтовый summary и
|
|
||||||
календарь могут жить рядом;
|
|
||||||
- для нашего UX слишком тяжел как direct reference.
|
|
||||||
|
|
||||||
Ссылка:
|
|
||||||
|
|
||||||
- https://www.thunderbird.net/en-US/
|
|
||||||
|
|
||||||
## Практический вывод
|
|
||||||
|
|
||||||
Лучшее направление для реализации:
|
|
||||||
|
|
||||||
- брать `Fantastical Mini Window` как референс формы;
|
|
||||||
- брать `GNOME Calendar` как референс календарных экранов;
|
|
||||||
- делать calendar-first popup;
|
|
||||||
- оставлять почту в формате короткого summary.
|
|
||||||
|
|
||||||
## Следующий логический шаг
|
|
||||||
|
|
||||||
Перед реализацией нужно решить:
|
|
||||||
|
|
||||||
1. popup должен быть очень маленьким overview-окном или уже почти полноценным
|
|
||||||
mini-organizer;
|
|
||||||
2. mini-mail нужен только для чтения summary или уже с действиями вроде
|
|
||||||
`mark read`, `archive`, `open`.
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# khal-calendar
|
|
||||||
|
|
||||||
Waybar custom calendar module that prints JSON with the current time and a Pango
|
|
||||||
tooltip. Event days and upcoming events are read from `khal`.
|
|
||||||
|
|
||||||
## Build On Bazzite
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/khal-calendar
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar
|
|
||||||
```
|
|
||||||
|
|
||||||
Waybar config should call the compiled binary:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
"exec": "~/.config/waybar/scripts/khal-calendar"
|
|
||||||
```
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# mail-counter
|
|
||||||
|
|
||||||
Waybar custom mail module for Thunderbird. It reads Thunderbird's
|
|
||||||
`global-messages-db.sqlite` and prints JSON for Waybar.
|
|
||||||
|
|
||||||
## Build On Bazzite
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/dotfiles/bazzite/mail-counter
|
|
||||||
cargo build --release
|
|
||||||
install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail
|
|
||||||
```
|
|
||||||
|
|
||||||
Waybar config should call the compiled binary:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
"exec": "~/.config/waybar/scripts/mail"
|
|
||||||
```
|
|
||||||
@@ -70,7 +70,7 @@ fn unread_count(db_path: &Path) -> i64 {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn waybar_json(count: i64) -> Value {
|
fn mail_json(count: i64) -> Value {
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
json!({
|
json!({
|
||||||
"text": format!("{MAIL_ICON} {count}"),
|
"text": format!("{MAIL_ICON} {count}"),
|
||||||
@@ -109,5 +109,5 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}", waybar_json(unread_count(&db_path)));
|
println!("{}", mail_json(unread_count(&db_path)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
|
// screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
|
||||||
spawn-at-startup "sh" "-c" "exec swaybg -i ~/Pictures/Wallpapers/raspberry.png -m fill"
|
spawn-at-startup "sh" "-c" "exec swaybg -i \"$HOME/.config/wallpaper.png\" -m fill"
|
||||||
spawn-at-startup "waybar"
|
spawn-at-startup "systemctl" "--user" "start" "quickshell-control-center.service"
|
||||||
hotkey-overlay {
|
hotkey-overlay {
|
||||||
// skip-at-startup
|
// skip-at-startup
|
||||||
}
|
}
|
||||||
@@ -322,9 +322,9 @@ window-rule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/-window-rule {
|
window-rule {
|
||||||
match app-id="code"
|
match app-id="code"
|
||||||
// opacity 0.98
|
opacity 0.8
|
||||||
border {
|
border {
|
||||||
// off
|
// off
|
||||||
}
|
}
|
||||||
@@ -450,8 +450,8 @@ binds {
|
|||||||
Mod+Shift+V { spawn "sh" "-c" "wl-paste -n | env DISPLAY=:0 xsel -ib"; }
|
Mod+Shift+V { spawn "sh" "-c" "wl-paste -n | env DISPLAY=:0 xsel -ib"; }
|
||||||
|
|
||||||
// Mod+T { spawn "sh" "-c" "alacritty msg create-window -e fish -C t || alacritty -e fish -C t"; }
|
// Mod+T { spawn "sh" "-c" "alacritty msg create-window -e fish -C t || alacritty -e fish -C t"; }
|
||||||
Mod+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; }
|
Mod+T { spawn "sh" "-c" "alacritty msg create-window -o window.opacity=0.5 || alacritty --option window.opacity=0.5"; }
|
||||||
Mod+Shift+T { spawn "alacritty"; }
|
Mod+Shift+T { spawn "alacritty" "--option" "window.opacity=0.5"; }
|
||||||
// Mod+Shift+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; }
|
// Mod+Shift+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; }
|
||||||
// Mod+Return { spawn "~/arst"; }
|
// Mod+Return { spawn "~/arst"; }
|
||||||
// Mod+T { spawn "flatpak" "run" "org.gnome.Ptyxis.Devel" "-s"; }
|
// Mod+T { spawn "flatpak" "run" "org.gnome.Ptyxis.Devel" "-s"; }
|
||||||
@@ -463,14 +463,16 @@ binds {
|
|||||||
Super+Alt+L allow-when-locked=true { spawn "swaylock"; }
|
Super+Alt+L allow-when-locked=true { spawn "swaylock"; }
|
||||||
|
|
||||||
Mod+W { spawn "sh" "-c" "mpv --pause \"$(wl-paste)\""; }
|
Mod+W { spawn "sh" "-c" "mpv --pause \"$(wl-paste)\""; }
|
||||||
// refresh.sh was a local Bazzite helper; keep these disabled until a Fedora helper exists.
|
// These refresh bindings stay disabled until a local Fedora helper exists.
|
||||||
// Super+Alt+H { spawn "refresh.sh" "144"; }
|
// Super+Alt+H { spawn "refresh.sh" "144"; }
|
||||||
// Super+Alt+Comma { spawn "refresh.sh" "120"; }
|
// Super+Alt+Comma { spawn "refresh.sh" "120"; }
|
||||||
|
|
||||||
XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"; }
|
XF86AudioRaiseVolume allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_up"; }
|
||||||
XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"; }
|
XF86AudioLowerVolume allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_down"; }
|
||||||
XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
XF86AudioMute allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_mute"; }
|
||||||
XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
|
XF86AudioMicMute allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd mic_mute"; }
|
||||||
|
XF86MonBrightnessUp allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd brightness_up"; }
|
||||||
|
XF86MonBrightnessDown allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd brightness_down"; }
|
||||||
|
|
||||||
Mod+Q { close-window; }
|
Mod+Q { close-window; }
|
||||||
Mod+BackSpace { close-window; }
|
Mod+BackSpace { close-window; }
|
||||||
|
|||||||
21
fedora/packages.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
niri
|
||||||
|
quickshell
|
||||||
|
fuzzel
|
||||||
|
alacritty
|
||||||
|
swaybg
|
||||||
|
swaylock
|
||||||
|
btop
|
||||||
|
glow
|
||||||
|
xsettingsd
|
||||||
|
pavucontrol
|
||||||
|
xsel
|
||||||
|
wl-clipboard
|
||||||
|
mpv
|
||||||
|
nautilus
|
||||||
|
khal
|
||||||
|
vdirsyncer
|
||||||
|
thunderbird
|
||||||
|
rustup
|
||||||
|
cargo
|
||||||
|
ddcutil
|
||||||
|
curl
|
||||||
517
fedora/quickshell/control-center/Bar.qml
Normal file
@@ -0,0 +1,517 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Services.Mpris
|
||||||
|
import Quickshell.Services.Pipewire
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: bar
|
||||||
|
|
||||||
|
property date currentTime: new Date()
|
||||||
|
|
||||||
|
property var controlCenter
|
||||||
|
property var settings
|
||||||
|
property var notificationCenter
|
||||||
|
property var mediaPopup
|
||||||
|
property var toggleMedia: null
|
||||||
|
property var workspaces: []
|
||||||
|
property string windowTitle: "Desktop"
|
||||||
|
property string language: "EN"
|
||||||
|
property string weather: "N/A"
|
||||||
|
property string gpu: "GPU N/A"
|
||||||
|
property string gpuTemperature: "--"
|
||||||
|
property string mail: ""
|
||||||
|
property int cpuUsage: 0
|
||||||
|
property int memoryUsage: 0
|
||||||
|
property string diskUsage: "--"
|
||||||
|
property string temperature: "--"
|
||||||
|
property var audioSink: Pipewire.defaultAudioSink
|
||||||
|
property var mediaPlayer: Mpris.players.values.find(player => player.playbackState === MprisPlaybackState.Playing)
|
||||||
|
|| Mpris.players.values[0]
|
||||||
|
|
||||||
|
function start(process) {
|
||||||
|
if (!process.running) process.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusWorkspace(index) {
|
||||||
|
Quickshell.execDetached(["niri", "msg", "action", "focus-workspace", String(index)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJson(collector, fallback) {
|
||||||
|
try {
|
||||||
|
const value = JSON.parse(collector.text);
|
||||||
|
return value === null ? fallback : value;
|
||||||
|
} catch (error) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: barWindow
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
implicitHeight: 40
|
||||||
|
exclusiveZone: 40
|
||||||
|
color: "transparent"
|
||||||
|
WlrLayershell.layer: WlrLayer.Top
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-bar"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: 4
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
anchors.rightMargin: 4
|
||||||
|
anchors.bottomMargin: 0
|
||||||
|
radius: 14
|
||||||
|
color: "#1e1e2e"
|
||||||
|
border.color: "#313244"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 6
|
||||||
|
anchors.rightMargin: 6
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: workspaceRow
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: bar.workspaces
|
||||||
|
delegate: Rectangle {
|
||||||
|
required property var modelData
|
||||||
|
implicitWidth: workspaceLabel.implicitWidth + 16
|
||||||
|
implicitHeight: 26
|
||||||
|
radius: 10
|
||||||
|
color: modelData.is_focused ? "#89b4fa" : (modelData.is_active ? "#45475a" : "#313244")
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: workspaceLabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: modelData.name || String(modelData.idx)
|
||||||
|
color: modelData.is_focused ? "#1e1e2e" : "#cdd6f4"
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: bar.focusWorkspace(modelData.idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.windowTitle
|
||||||
|
color: "#cdd6f4"
|
||||||
|
font.pixelSize: 15
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.maximumWidth: 420
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.weather
|
||||||
|
color: "#89dceb"
|
||||||
|
font.pixelSize: 15
|
||||||
|
ToolTip.visible: weatherMouse.containsMouse
|
||||||
|
ToolTip.text: "Weather"
|
||||||
|
MouseArea {
|
||||||
|
id: weatherMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: bar.mail.length > 0
|
||||||
|
text: bar.mail
|
||||||
|
color: "#b4befe"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "mail"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: mailMouse.containsMouse
|
||||||
|
ToolTip.text: "Unread mail"
|
||||||
|
MouseArea {
|
||||||
|
id: mailMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: Quickshell.execDetached(["thunderbird"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: bar.mediaPlayer !== null
|
||||||
|
text: bar.mediaPlayer ? (bar.mediaPlayer.trackTitle || bar.mediaPlayer.identity) : ""
|
||||||
|
color: "#f5c2e7"
|
||||||
|
leftPadding: 19
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.maximumWidth: 190
|
||||||
|
BarIcon { name: "audio"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: mediaMouse.containsMouse
|
||||||
|
ToolTip.text: "Open media controls"
|
||||||
|
MouseArea {
|
||||||
|
id: mediaMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (bar.toggleMedia) bar.toggleMedia();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: !!bar.notificationCenter && bar.notificationCenter.count > 0
|
||||||
|
text: bar.notificationCenter ? String(bar.notificationCenter.count) : ""
|
||||||
|
color: "#f38ba8"
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "mail"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: notificationMouse.containsMouse
|
||||||
|
ToolTip.text: "Open notifications"
|
||||||
|
MouseArea {
|
||||||
|
id: notificationMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (bar.notificationCenter) bar.notificationCenter.open = !bar.notificationCenter.open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.gpu
|
||||||
|
color: "#a6e3a1"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "gpu"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: gpuMouse.containsMouse
|
||||||
|
ToolTip.text: "GPU usage"
|
||||||
|
MouseArea {
|
||||||
|
id: gpuMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.cpuUsage + "%"
|
||||||
|
color: "#a6e3a1"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "cpu"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: cpuMouse.containsMouse
|
||||||
|
ToolTip.text: "CPU usage"
|
||||||
|
MouseArea { id: cpuMouse; anchors.fill: parent }
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.memoryUsage + "%"
|
||||||
|
color: "#cba6f7"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "memory"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: memoryMouse.containsMouse
|
||||||
|
ToolTip.text: "Memory usage"
|
||||||
|
MouseArea { id: memoryMouse; anchors.fill: parent }
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.diskUsage
|
||||||
|
color: "#f38ba8"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "disk"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: diskMouse.containsMouse
|
||||||
|
ToolTip.text: "Root filesystem"
|
||||||
|
MouseArea { id: diskMouse; anchors.fill: parent }
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.language
|
||||||
|
color: "#94e2d5"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "language"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: languageMouse.containsMouse
|
||||||
|
ToolTip.text: "Keyboard layout"
|
||||||
|
MouseArea { id: languageMouse; anchors.fill: parent }
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: bar.audioSink && bar.audioSink.audio
|
||||||
|
? Math.round(bar.audioSink.audio.volume * 100) + "%"
|
||||||
|
: "--"
|
||||||
|
color: "#f9e2af"
|
||||||
|
font.pixelSize: 15
|
||||||
|
leftPadding: 19
|
||||||
|
BarIcon { name: "audio"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter }
|
||||||
|
ToolTip.visible: audioMouse.containsMouse
|
||||||
|
ToolTip.text: "Audio output"
|
||||||
|
MouseArea {
|
||||||
|
id: audioMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (bar.audioSink && bar.audioSink.audio) bar.audioSink.audio.muted = !bar.audioSink.audio.muted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: Qt.formatDateTime(bar.currentTime, "dd.MM HH:mm")
|
||||||
|
color: "#cdd6f4"
|
||||||
|
font.pixelSize: 15
|
||||||
|
ToolTip.visible: clockMouse.containsMouse
|
||||||
|
ToolTip.text: "Open calendar"
|
||||||
|
MouseArea {
|
||||||
|
id: clockMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: Quickshell.execDetached(["sh", "-c", "alacritty --title khal-popup -e bash -c 'vdirsyncer sync 2>/dev/null; ikhal'"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: ""
|
||||||
|
color: "#89b4fa"
|
||||||
|
Layout.preferredWidth: 18
|
||||||
|
Layout.minimumWidth: 18
|
||||||
|
Layout.maximumWidth: 18
|
||||||
|
BarIcon { name: "gear"; size: 18; anchors.centerIn: parent }
|
||||||
|
ToolTip.visible: settingsMouse.containsMouse
|
||||||
|
ToolTip.text: "Quick settings"
|
||||||
|
MouseArea {
|
||||||
|
id: settingsMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (bar.controlCenter) bar.controlCenter.togglePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: SystemTray.items
|
||||||
|
delegate: Item {
|
||||||
|
required property var modelData
|
||||||
|
property bool hiddenTrayItem: !modelData
|
||||||
|
|| /wayland to x11 video bridge|screen sharing|screen share/i.test(String(modelData.title || ""))
|
||||||
|
|| /video-display|screen-share|screen-sharing/i.test(String(modelData.icon || ""))
|
||||||
|
visible: !hiddenTrayItem
|
||||||
|
implicitWidth: hiddenTrayItem ? 0 : 20
|
||||||
|
implicitHeight: 22
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: trayIcon
|
||||||
|
anchors.fill: parent
|
||||||
|
active: !hiddenTrayItem && modelData
|
||||||
|
sourceComponent: Component {
|
||||||
|
IconImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitSize: 18
|
||||||
|
source: modelData && modelData.icon && modelData.icon.startsWith("image://")
|
||||||
|
? modelData.icon
|
||||||
|
: (modelData ? Quickshell.iconPath(modelData.icon) : "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarIcon {
|
||||||
|
visible: !hiddenTrayItem && !trayIcon.active
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: !hiddenTrayItem
|
||||||
|
name: "video"
|
||||||
|
size: 15
|
||||||
|
anchors.margins: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
onClicked: function(mouse) {
|
||||||
|
if (!modelData) return;
|
||||||
|
if (mouse.button === Qt.RightButton && modelData.hasMenu) {
|
||||||
|
modelData.display(barWindow, mouse.x, mouse.y + 20);
|
||||||
|
} else {
|
||||||
|
modelData.activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PwObjectTracker {
|
||||||
|
objects: [bar.audioSink]
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: workspaceReader
|
||||||
|
command: ["niri", "msg", "-j", "workspaces"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = bar.parseJson(this, []);
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.sort((left, right) => left.idx - right.idx);
|
||||||
|
bar.workspaces = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: windowReader
|
||||||
|
command: ["niri", "msg", "-j", "focused-window"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = bar.parseJson(this, {});
|
||||||
|
bar.windowTitle = value.title || "Desktop";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: languageReader
|
||||||
|
command: ["niri", "msg", "-j", "keyboard-layouts"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = bar.parseJson(this, {});
|
||||||
|
const index = Number(value.current_idx);
|
||||||
|
const name = Array.isArray(value.names) && index >= 0 ? String(value.names[index] || "") : "";
|
||||||
|
const normalized = name.toLowerCase();
|
||||||
|
if (normalized.includes("russian") || normalized.includes("рус")) bar.language = "RU";
|
||||||
|
else if (normalized.includes("english") || normalized.includes("англ")) bar.language = "EN";
|
||||||
|
else if (name.length > 0) bar.language = name.slice(0, 2).toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: cpuReader
|
||||||
|
command: ["sh", "-c", "awk '/^cpu / { idle=$5; total=0; for (i=2; i<=NF; i++) total += $i; print int((total-idle)*100/total) }' /proc/stat"]
|
||||||
|
stdout: StdioCollector { onStreamFinished: bar.cpuUsage = parseInt(text.trim()) || 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: memoryReader
|
||||||
|
command: ["sh", "-c", "free | awk '/^Mem:/ { print int($3*100/$2) }'"]
|
||||||
|
stdout: StdioCollector { onStreamFinished: bar.memoryUsage = parseInt(text.trim()) || 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: diskReader
|
||||||
|
command: ["sh", "-c", "df -P / | awk 'NR==2 { print $5 }'"]
|
||||||
|
stdout: StdioCollector { onStreamFinished: bar.diskUsage = text.trim() || "--" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: temperatureReader
|
||||||
|
command: ["sh", "-c", "max=0; for file in /sys/class/thermal/thermal_zone*/temp; do value=$(cat $file 2>/dev/null); [ $value -gt $max ] 2>/dev/null && max=$value; done; if [ $max -gt 0 ]; then echo $((max / 1000))C; else echo --; fi"]
|
||||||
|
stdout: StdioCollector { onStreamFinished: bar.temperature = text.trim() || "--" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: gpuReader
|
||||||
|
command: ["sh", "-c", "nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null | head -1"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const parts = text.trim().split(",");
|
||||||
|
const usage = parseInt((parts[0] || "").trim());
|
||||||
|
const temperature = parseInt((parts[1] || "").trim());
|
||||||
|
bar.gpu = isNaN(usage) ? "N/A" : usage + "%";
|
||||||
|
bar.gpuTemperature = isNaN(temperature) ? "--" : temperature + "C";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: weatherReader
|
||||||
|
command: ["bash", Quickshell.shellPath("../scripts/weather.sh")]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = bar.parseJson(this, {});
|
||||||
|
bar.weather = value.text || "N/A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: mailReader
|
||||||
|
command: ["sh", "-c", "if [ -x $HOME/.local/bin/mail-counter ]; then $HOME/.local/bin/mail-counter; else printf '{}'; fi"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = bar.parseJson(this, {});
|
||||||
|
bar.mail = value.text || "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: refreshTimer
|
||||||
|
interval: bar.settings ? bar.settings.temperatureInterval : 2000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
bar.currentTime = new Date();
|
||||||
|
bar.start(windowReader);
|
||||||
|
bar.start(cpuReader);
|
||||||
|
bar.start(memoryReader);
|
||||||
|
bar.start(diskReader);
|
||||||
|
bar.start(temperatureReader);
|
||||||
|
bar.start(gpuReader);
|
||||||
|
bar.start(mailReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: weatherTimer
|
||||||
|
interval: 900000
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: bar.start(weatherReader)
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: languageTimer
|
||||||
|
interval: 200
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: bar.start(languageReader)
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: workspaceTimer
|
||||||
|
interval: 100
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: bar.start(workspaceReader)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
bar.start(workspaceReader);
|
||||||
|
bar.start(windowReader);
|
||||||
|
bar.start(languageReader);
|
||||||
|
bar.start(cpuReader);
|
||||||
|
bar.start(memoryReader);
|
||||||
|
bar.start(diskReader);
|
||||||
|
bar.start(temperatureReader);
|
||||||
|
bar.start(gpuReader);
|
||||||
|
bar.start(weatherReader);
|
||||||
|
bar.start(mailReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
fedora/quickshell/control-center/BarIcon.qml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string name
|
||||||
|
property real size: 15
|
||||||
|
|
||||||
|
width: size
|
||||||
|
height: size
|
||||||
|
source: Qt.resolvedUrl("icons/" + name + ".svg")
|
||||||
|
sourceSize.width: size * 2
|
||||||
|
sourceSize.height: size * 2
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
209
fedora/quickshell/control-center/MediaPopup.qml
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.Mpris
|
||||||
|
import Quickshell.Wayland
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool open: false
|
||||||
|
property var selectedPlayer: null
|
||||||
|
property var player: selectedPlayer
|
||||||
|
|| Mpris.players.values.find(candidate => candidate.playbackState === MprisPlaybackState.Playing)
|
||||||
|
|| Mpris.players.values[0]
|
||||||
|
|| null
|
||||||
|
|
||||||
|
signal dismissed()
|
||||||
|
|
||||||
|
function formatTime(value) {
|
||||||
|
if (!value || value < 0) return "0:00";
|
||||||
|
const seconds = Math.floor(value);
|
||||||
|
return Math.floor(seconds / 60) + ":" + String(seconds % 60).padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
visible: root.open
|
||||||
|
color: "transparent"
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-media-popup"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.dismissed()
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: card
|
||||||
|
width: Math.min(410, parent.width - 32)
|
||||||
|
height: root.player ? 330 : 150
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.topMargin: 52
|
||||||
|
radius: 20
|
||||||
|
color: "#f5f2ea"
|
||||||
|
border.color: "#d8d0c2"
|
||||||
|
border.width: 1
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: function(mouse) { mouse.accepted = true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 16
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Media"
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 20
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.player ? root.player.identity : "No player"
|
||||||
|
color: "#7c756c"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
width: 26
|
||||||
|
height: 26
|
||||||
|
radius: 13
|
||||||
|
color: "#e5e0d7"
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "x"
|
||||||
|
color: "#6e675f"
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.dismissed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: root.player !== null
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 14
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredWidth: 132
|
||||||
|
Layout.preferredHeight: 132
|
||||||
|
radius: 14
|
||||||
|
color: "#e5e0d7"
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: cover
|
||||||
|
anchors.fill: parent
|
||||||
|
source: root.player ? root.player.trackArtUrl : ""
|
||||||
|
fillMode: Image.PreserveAspectCrop
|
||||||
|
asynchronous: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: cover.status !== Image.Ready
|
||||||
|
text: "♪"
|
||||||
|
color: "#8b8176"
|
||||||
|
font.pixelSize: 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: root.player ? (root.player.trackTitle || "Unknown track") : ""
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 17
|
||||||
|
font.bold: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.player ? (root.player.trackArtist || root.player.trackAlbum || "Unknown artist") : ""
|
||||||
|
color: "#7c756c"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Item { Layout.fillHeight: true }
|
||||||
|
Label {
|
||||||
|
text: root.player ? root.formatTime(root.player.position) + " / " + root.formatTime(root.player.length) : ""
|
||||||
|
color: "#7c756c"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
visible: root.player && root.player.length > 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 0
|
||||||
|
to: root.player ? root.player.length : 1
|
||||||
|
value: root.player ? root.player.position : 0
|
||||||
|
onMoved: {
|
||||||
|
if (root.player && root.player.canSeek) root.player.position = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: root.player !== null
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 14
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Prev"
|
||||||
|
enabled: !!(root.player && root.player.canGoPrevious)
|
||||||
|
onClicked: root.player.previous()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: root.player && root.player.playbackState === MprisPlaybackState.Playing ? "Pause" : "Play"
|
||||||
|
enabled: !!(root.player && root.player.canTogglePlaying)
|
||||||
|
onClicked: root.player.togglePlaying()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Next"
|
||||||
|
enabled: !!(root.player && root.player.canGoNext)
|
||||||
|
onClicked: root.player.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: Mpris.players.values.length > 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Players"
|
||||||
|
color: "#7c756c"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Repeater {
|
||||||
|
model: Mpris.players
|
||||||
|
delegate: Button {
|
||||||
|
required property var modelData
|
||||||
|
text: modelData.identity
|
||||||
|
onClicked: root.selectedPlayer = modelData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
220
fedora/quickshell/control-center/Notifications.qml
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import Quickshell.Wayland
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool open: false
|
||||||
|
property bool dnd: false
|
||||||
|
property bool toastOpen: false
|
||||||
|
property var latest: null
|
||||||
|
readonly property int count: server.trackedNotifications ? server.trackedNotifications.values.length : 0
|
||||||
|
|
||||||
|
signal dismissed()
|
||||||
|
|
||||||
|
NotificationServer {
|
||||||
|
id: server
|
||||||
|
keepOnReload: true
|
||||||
|
onNotification: function(notification) {
|
||||||
|
notification.tracked = true;
|
||||||
|
root.latest = notification;
|
||||||
|
if (!root.dnd) {
|
||||||
|
root.toastOpen = true;
|
||||||
|
toastTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: toastTimer
|
||||||
|
interval: 5000
|
||||||
|
repeat: false
|
||||||
|
onTriggered: root.toastOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
visible: root.toastOpen && !root.open && root.latest !== null
|
||||||
|
color: "transparent"
|
||||||
|
anchors { top: true; bottom: true; left: true; right: true }
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-notification-toast"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: Math.min(390, parent.width - 32)
|
||||||
|
height: 100
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 16
|
||||||
|
radius: 16
|
||||||
|
color: "#f5f2ea"
|
||||||
|
border.color: "#d8d0c2"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
root.toastOpen = false;
|
||||||
|
root.open = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 14
|
||||||
|
spacing: 3
|
||||||
|
Label {
|
||||||
|
text: root.latest ? root.latest.appName : ""
|
||||||
|
color: "#7c756c"
|
||||||
|
font.pixelSize: 11
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.latest ? root.latest.summary : ""
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.latest ? root.latest.body : ""
|
||||||
|
color: "#5f5952"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
visible: root.open
|
||||||
|
color: "transparent"
|
||||||
|
anchors { top: true; bottom: true; left: true; right: true }
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-notification-center"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.dismissed()
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: Math.min(430, parent.width - 32)
|
||||||
|
height: Math.min(parent.height - 32, 700)
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 16
|
||||||
|
radius: 20
|
||||||
|
color: "#f5f2ea"
|
||||||
|
border.color: "#d8d0c2"
|
||||||
|
border.width: 1
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: function(mouse) { mouse.accepted = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 18
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Notifications"
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 22
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: root.dnd ? "DND on" : "DND off"
|
||||||
|
onClicked: root.dnd = !root.dnd
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Close"
|
||||||
|
onClicked: root.dismissed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: root.count === 0
|
||||||
|
text: "No notifications"
|
||||||
|
color: "#7c756c"
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: 18
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: server.trackedNotifications
|
||||||
|
delegate: Rectangle {
|
||||||
|
required property var modelData
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: notificationColumn.implicitHeight + 22
|
||||||
|
radius: 14
|
||||||
|
color: "#e8e3da"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: notificationColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 11
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: modelData.appName
|
||||||
|
color: "#7c756c"
|
||||||
|
font.pixelSize: 11
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "x"
|
||||||
|
onClicked: modelData.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: modelData.summary
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: modelData.body
|
||||||
|
color: "#5f5952"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
fedora/quickshell/control-center/Osd.qml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool open: false
|
||||||
|
property string kind: "volume"
|
||||||
|
property real value: 0
|
||||||
|
property bool muted: false
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
visible: root.open
|
||||||
|
color: "transparent"
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-osd"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 78
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 110
|
||||||
|
radius: 20
|
||||||
|
color: "#1e1e2e"
|
||||||
|
border.color: "#45475a"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 16
|
||||||
|
spacing: 12
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: root.kind === "brightness" ? "Display" : (root.muted ? "Muted" : "Volume")
|
||||||
|
color: "#cdd6f4"
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 8
|
||||||
|
radius: 4
|
||||||
|
color: "#313244"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width * Math.max(0, Math.min(1, root.value))
|
||||||
|
height: parent.height
|
||||||
|
radius: 4
|
||||||
|
color: root.kind === "brightness" ? "#f9e2af" : "#89b4fa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: Math.round(root.value * 100) + "%"
|
||||||
|
color: "#cdd6f4"
|
||||||
|
font.pixelSize: 15
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
fedora/quickshell/control-center/Settings.qml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias temperatureInterval: values.temperatureInterval
|
||||||
|
property alias temperatureWarning: values.temperatureWarning
|
||||||
|
property alias temperatureCritical: values.temperatureCritical
|
||||||
|
|
||||||
|
function setTemperatureWarning(value) {
|
||||||
|
root.temperatureWarning = Math.min(value, root.temperatureCritical - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTemperatureCritical(value) {
|
||||||
|
root.temperatureCritical = Math.max(value, root.temperatureWarning + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
property FileView settingsFile: FileView {
|
||||||
|
path: Quickshell.statePath("control-center.json")
|
||||||
|
printErrors: false
|
||||||
|
watchChanges: true
|
||||||
|
onFileChanged: reload()
|
||||||
|
onAdapterUpdated: writeAdapter()
|
||||||
|
|
||||||
|
JsonAdapter {
|
||||||
|
id: values
|
||||||
|
|
||||||
|
property int temperatureInterval: 2000
|
||||||
|
property int temperatureWarning: 75
|
||||||
|
property int temperatureCritical: 90
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
fedora/quickshell/control-center/icons/audio.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#f9e2af" d="M3 9v6h4l5 4V5L7 9H3Zm13.5 3a4.5 4.5 0 0 0-2.5-4.03v8.06A4.5 4.5 0 0 0 16.5 12Zm0-8v2.12A6.98 6.98 0 0 1 20 12a6.98 6.98 0 0 1-3.5 5.88V20a9 9 0 0 0 0-16Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 248 B |
1
fedora/quickshell/control-center/icons/cpu.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#a6e3a1" d="M4 4h16v16H4V4Zm3 3v10h10V7H7Zm2 2h6v6H9V9Zm-7 2H0v2h2v-2Zm20 0h2v2h-2v-2ZM11 0h2v2h-2V0Zm0 22h2v2h-2v-2Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 199 B |
1
fedora/quickshell/control-center/icons/disk.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#f38ba8" d="M3 5h18v14H3V5Zm3 3v8h12V8H6Zm2 2h8v4H8v-4Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 137 B |
1
fedora/quickshell/control-center/icons/gear.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#89b4fa" d="m19.43 12.98.04-.98-.04-.98 2.11-1.65-2-3.46-2.49 1a7.7 7.7 0 0 0-1.7-.98L15 3h-4l-.35 2.93c-.6.25-1.17.58-1.7.98l-2.49-1-2 3.46 2.11 1.65-.04.98.04.98-2.11 1.65 2 3.46 2.49-1c.53.4 1.1.73 1.7.98L11 21h4l.35-2.93a7.7 7.7 0 0 0 1.7-.98l2.49 1 2-3.46-2.11-1.65ZM13 15.5A3.5 3.5 0 1 1 13 8a3.5 3.5 0 0 1 0 7.5Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 401 B |
1
fedora/quickshell/control-center/icons/gpu.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#a6e3a1" d="M2 5h20v14H2V5Zm2 2v10h16V7H4Zm2 2h6v6H6V9Zm2 2v2h2v-2H8Zm8-2h2v2h-2V9Zm0 4h2v2h-2v-2ZM0 9h2v2H0V9Zm0 4h2v2H0v-2Zm22-4h2v2h-2V9Zm0 4h2v2h-2v-2Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 237 B |
1
fedora/quickshell/control-center/icons/language.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#94e2d5" d="M4 20 9 4h2l5 16h-2l-1.25-4h-5.5L6 20H4Zm4.88-6h3.24L10.5 8.8 8.88 14ZM15 6h7v2h-2.5c-.38 3-1.42 5.47-3.12 7.4.9.8 1.94 1.5 3.12 2.1v2.2a16.2 16.2 0 0 1-4.45-2.86A16 16 0 0 1 12 19v-2.2c.98-.58 1.88-1.3 2.7-2.18A14.3 14.3 0 0 1 12.8 11h2.1c.27.7.65 1.4 1.15 2.08A12.7 12.7 0 0 0 17.4 8H15V6Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 385 B |
1
fedora/quickshell/control-center/icons/mail.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#b4befe" d="M3 5h18a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2Zm0 3v1l9 5 9-5V8l-9 5-9-5Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 191 B |
1
fedora/quickshell/control-center/icons/memory.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#cba6f7" d="M3 3h18v4H3V3Zm0 7h18v4H3v-4Zm0 7h18v4H3v-4Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 138 B |
1
fedora/quickshell/control-center/icons/temperature.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#fab387" d="M14 14.76V5a2 2 0 0 0-4 0v9.76a5 5 0 1 0 4 0ZM12 20a3 3 0 0 1-1-5.83V5a1 1 0 0 1 2 0v9.17A3 3 0 0 1 12 20Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 200 B |
1
fedora/quickshell/control-center/icons/video.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#cdd6f4" d="M3 5h13a2 2 0 0 1 2 2v2l4-2v10l-4-2v2a2 2 0 0 1-2 2H3V5Zm2 3v8h11V8H5Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 164 B |
748
fedora/quickshell/control-center/shell.qml
Normal file
@@ -0,0 +1,748 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Bluetooth
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Networking
|
||||||
|
import Quickshell.Services.Pipewire
|
||||||
|
import Quickshell.Services.UPower
|
||||||
|
import Quickshell.Wayland
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool open: false
|
||||||
|
property bool panelVisible: false
|
||||||
|
property bool mediaOpen: false
|
||||||
|
property bool notificationsOpen: false
|
||||||
|
property bool osdOpen: false
|
||||||
|
property string osdKind: "volume"
|
||||||
|
property int brightness: 0
|
||||||
|
property var pendingNetwork: null
|
||||||
|
property string wifiPassword: ""
|
||||||
|
property var wifiDevice: Networking.devices.values.find(device => device.type === DeviceType.Wifi)
|
||||||
|
property var bluetoothAdapter: Bluetooth.defaultAdapter
|
||||||
|
property var audioSink: Pipewire.defaultAudioSink
|
||||||
|
property var settings: statusSettings
|
||||||
|
property alias cpuTemperature: statusBar.temperature
|
||||||
|
property alias gpuTemperature: statusBar.gpuTemperature
|
||||||
|
|
||||||
|
Settings {
|
||||||
|
id: statusSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar {
|
||||||
|
id: statusBar
|
||||||
|
controlCenter: root
|
||||||
|
settings: root.settings
|
||||||
|
mediaPopup: mediaPopup
|
||||||
|
toggleMedia: function() { root.mediaOpen = !root.mediaOpen }
|
||||||
|
notificationCenter: notificationCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaPopup {
|
||||||
|
id: mediaPopup
|
||||||
|
open: root.mediaOpen
|
||||||
|
onDismissed: root.mediaOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Notifications {
|
||||||
|
id: notificationCenter
|
||||||
|
open: root.notificationsOpen
|
||||||
|
onDismissed: root.notificationsOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Osd {
|
||||||
|
open: root.osdOpen
|
||||||
|
kind: root.osdKind
|
||||||
|
value: root.osdKind === "brightness"
|
||||||
|
? root.brightness / 100
|
||||||
|
: (root.audioSink && root.audioSink.audio ? root.audioSink.audio.volume : 0)
|
||||||
|
muted: root.audioSink && root.audioSink.audio ? root.audioSink.audio.muted : false
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBrightness(value) {
|
||||||
|
const level = Math.max(0, Math.min(100, Math.round(value)));
|
||||||
|
Quickshell.execDetached(["ddcutil", "setvcp", "10", String(level)]);
|
||||||
|
root.brightness = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectWifi(network) {
|
||||||
|
if (network.security === WifiSecurityType.Open) {
|
||||||
|
network.connect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.pendingNetwork = network;
|
||||||
|
root.wifiPassword = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitWifiPassword() {
|
||||||
|
if (root.pendingNetwork && root.wifiPassword.length > 0) {
|
||||||
|
root.pendingNetwork.connectWithPsk(root.wifiPassword);
|
||||||
|
root.pendingNetwork = null;
|
||||||
|
root.wifiPassword = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOsd(kind) {
|
||||||
|
root.osdKind = kind;
|
||||||
|
root.osdOpen = true;
|
||||||
|
osdTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function adjustBrightness(delta) {
|
||||||
|
const current = root.brightness > 0 ? root.brightness : 50;
|
||||||
|
root.setBrightness(current + delta);
|
||||||
|
root.showOsd("brightness");
|
||||||
|
}
|
||||||
|
|
||||||
|
function temperatureColor(value) {
|
||||||
|
const match = String(value).match(/(\d+)C\s*$/);
|
||||||
|
const temperature = match ? Number(match[1]) : -1;
|
||||||
|
if (temperature < 0) return "#806d95";
|
||||||
|
if (temperature >= root.settings.temperatureCritical) return "#c94f6d";
|
||||||
|
if (temperature >= root.settings.temperatureWarning) return "#996315";
|
||||||
|
return "#4d7c38";
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPanel() {
|
||||||
|
closePanelTimer.stop();
|
||||||
|
root.panelVisible = true;
|
||||||
|
openPanelTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePanel() {
|
||||||
|
openPanelTimer.stop();
|
||||||
|
root.open = false;
|
||||||
|
closePanelTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePanel() {
|
||||||
|
if (root.open || root.panelVisible) root.closePanel();
|
||||||
|
else root.openPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: openPanelTimer
|
||||||
|
interval: 1
|
||||||
|
repeat: false
|
||||||
|
onTriggered: root.open = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: closePanelTimer
|
||||||
|
interval: 240
|
||||||
|
repeat: false
|
||||||
|
onTriggered: root.panelVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "controlcenter"
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
root.togglePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
root.openPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
root.closePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "osd"
|
||||||
|
|
||||||
|
function volume_up() {
|
||||||
|
Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+"]);
|
||||||
|
root.showOsd("volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
function volume_down() {
|
||||||
|
Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]);
|
||||||
|
root.showOsd("volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
function volume_mute() {
|
||||||
|
Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle"]);
|
||||||
|
root.showOsd("volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
function mic_mute() {
|
||||||
|
Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"]);
|
||||||
|
root.showOsd("mic");
|
||||||
|
}
|
||||||
|
|
||||||
|
function brightness_up() {
|
||||||
|
root.adjustBrightness(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function brightness_down() {
|
||||||
|
root.adjustBrightness(-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: osdTimer
|
||||||
|
interval: 1400
|
||||||
|
repeat: false
|
||||||
|
onTriggered: root.osdOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
PwObjectTracker {
|
||||||
|
objects: [root.audioSink]
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: brightnessReader
|
||||||
|
command: ["sh", "-c", "ddcutil getvcp 10 2>/dev/null | sed -n 's/.*current value = *\\([0-9]*\\).*/\\1/p'"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const value = parseInt(text.trim());
|
||||||
|
if (!isNaN(value)) root.brightness = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: brightnessPoll
|
||||||
|
interval: 3000
|
||||||
|
repeat: true
|
||||||
|
running: root.open
|
||||||
|
onTriggered: {
|
||||||
|
if (!brightnessReader.running) brightnessReader.running = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
visible: root.panelVisible
|
||||||
|
color: "transparent"
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
WlrLayershell.keyboardFocus: root.panelVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
WlrLayershell.namespace: "quickshell-control-center"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.closePanel()
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: card
|
||||||
|
width: Math.min(470, parent.width - 32)
|
||||||
|
height: parent.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 0
|
||||||
|
x: root.open ? parent.width - width - 16 : parent.width + 24
|
||||||
|
radius: 20
|
||||||
|
color: "#f5f2ea"
|
||||||
|
border.color: "#d8d0c2"
|
||||||
|
border.width: 1
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 220
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: mouse.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 18
|
||||||
|
spacing: 12
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Control center"
|
||||||
|
color: "#252321"
|
||||||
|
font.pixelSize: 22
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "Niri / QuickShell"
|
||||||
|
color: "#7c756c"
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "✕"
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: "Close"
|
||||||
|
onClicked: root.closePanel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: wifiColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#e5f0ef"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: wifiColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Wi-Fi"
|
||||||
|
color: "#1c666d"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.wifiDevice ? (root.wifiDevice.name || "Available") : "Unavailable"
|
||||||
|
color: "#52777a"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Switch {
|
||||||
|
checked: Networking.wifiEnabled
|
||||||
|
enabled: Networking.wifiHardwareEnabled
|
||||||
|
onToggled: Networking.wifiEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: root.wifiDevice !== null
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: root.wifiDevice && root.wifiDevice.networks.values.find(network => network.connected)
|
||||||
|
? root.wifiDevice.networks.values.find(network => network.connected).name
|
||||||
|
: "Not connected"
|
||||||
|
color: "#252321"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Scan"
|
||||||
|
onClicked: {
|
||||||
|
if (root.wifiDevice) root.wifiDevice.scannerEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.wifiDevice ? root.wifiDevice.networks : null
|
||||||
|
delegate: RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: modelData.name
|
||||||
|
color: "#252321"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: modelData.connected ? "Connected" : Math.round(modelData.signalStrength) + "%"
|
||||||
|
color: modelData.connected ? "#1c666d" : "#7c756c"
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: modelData.connected ? "Disconnect" : "Connect"
|
||||||
|
enabled: !modelData.stateChanging
|
||||||
|
onClicked: modelData.connected ? modelData.disconnect() : root.connectWifi(modelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: root.pendingNetwork !== null
|
||||||
|
Layout.fillWidth: true
|
||||||
|
TextField {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderText: "Password for " + (root.pendingNetwork ? root.pendingNetwork.name : "network")
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
text: root.wifiPassword
|
||||||
|
onTextChanged: root.wifiPassword = text
|
||||||
|
onAccepted: root.submitWifiPassword()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Join"
|
||||||
|
enabled: root.wifiPassword.length > 0
|
||||||
|
onClicked: root.submitWifiPassword()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: bluetoothColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#eceafd"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: bluetoothColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Bluetooth"
|
||||||
|
color: "#55499c"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Switch {
|
||||||
|
checked: root.bluetoothAdapter ? root.bluetoothAdapter.enabled : false
|
||||||
|
enabled: root.bluetoothAdapter !== null
|
||||||
|
onToggled: {
|
||||||
|
if (root.bluetoothAdapter) root.bluetoothAdapter.enabled = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: root.bluetoothAdapter && root.bluetoothAdapter.discovering ? "Stop scan" : "Scan"
|
||||||
|
enabled: root.bluetoothAdapter && root.bluetoothAdapter.enabled
|
||||||
|
onClicked: {
|
||||||
|
if (root.bluetoothAdapter) root.bluetoothAdapter.discovering = !root.bluetoothAdapter.discovering;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.bluetoothAdapter ? root.bluetoothAdapter.devices : null
|
||||||
|
delegate: RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
Label {
|
||||||
|
text: modelData.name || modelData.deviceName || "Unknown device"
|
||||||
|
color: "#252321"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: modelData.connected ? "Connected" : (modelData.paired ? "Paired" : "Not paired")
|
||||||
|
color: "#7c756c"
|
||||||
|
font.pixelSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
visible: modelData.batteryAvailable
|
||||||
|
text: Math.round(modelData.battery * 100) + "%"
|
||||||
|
color: "#7c756c"
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: modelData.connected ? "Disconnect" : (modelData.paired ? "Connect" : "Pair")
|
||||||
|
onClicked: {
|
||||||
|
if (modelData.connected) modelData.disconnect();
|
||||||
|
else if (modelData.paired) modelData.connect();
|
||||||
|
else modelData.pair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: audioColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#fff1d7"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: audioColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Audio"
|
||||||
|
color: "#996315"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.audioSink ? (root.audioSink.description || "Default output") : "Unavailable"
|
||||||
|
color: "#806a48"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.maximumWidth: 230
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Button {
|
||||||
|
text: root.audioSink && root.audioSink.audio && root.audioSink.audio.muted ? "Unmute" : "Mute"
|
||||||
|
enabled: root.audioSink && root.audioSink.audio
|
||||||
|
onClicked: {
|
||||||
|
if (root.audioSink && root.audioSink.audio) root.audioSink.audio.muted = !root.audioSink.audio.muted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Slider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 0
|
||||||
|
to: 1
|
||||||
|
value: root.audioSink && root.audioSink.audio ? root.audioSink.audio.volume : 0
|
||||||
|
enabled: root.audioSink && root.audioSink.audio
|
||||||
|
onMoved: {
|
||||||
|
if (root.audioSink && root.audioSink.audio) root.audioSink.audio.volume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.audioSink && root.audioSink.audio ? Math.round(root.audioSink.audio.volume * 100) + "%" : "--"
|
||||||
|
color: "#806a48"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Pipewire.nodes
|
||||||
|
delegate: RowLayout {
|
||||||
|
visible: modelData.isSink && !modelData.isStream
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: modelData.description || modelData.name
|
||||||
|
color: "#252321"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: modelData === root.audioSink ? "Default" : "Use"
|
||||||
|
enabled: modelData !== root.audioSink
|
||||||
|
onClicked: Pipewire.preferredDefaultAudioSink = modelData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: displayColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#f8e4dc"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: displayColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Display brightness"
|
||||||
|
color: "#9e4d39"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.brightness > 0 ? root.brightness + "%" : "Unavailable"
|
||||||
|
color: "#8b665b"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Slider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 1
|
||||||
|
to: 100
|
||||||
|
value: root.brightness
|
||||||
|
enabled: root.brightness > 0
|
||||||
|
onPressedChanged: {
|
||||||
|
if (!pressed) root.setBrightness(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: statusColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#eee8f7"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: statusColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Status bar"
|
||||||
|
color: "#684b8f"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "Temperature"
|
||||||
|
color: "#806d95"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "CPU temperature"
|
||||||
|
color: "#252321"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.cpuTemperature
|
||||||
|
color: root.temperatureColor(root.cpuTemperature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "GPU temperature"
|
||||||
|
color: "#252321"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: root.gpuTemperature
|
||||||
|
color: root.temperatureColor(root.gpuTemperature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Refresh interval"
|
||||||
|
color: "#252321"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
model: ["1 second", "2 seconds", "5 seconds"]
|
||||||
|
currentIndex: [1000, 2000, 5000].indexOf(root.settings.temperatureInterval)
|
||||||
|
onActivated: root.settings.temperatureInterval = [1000, 2000, 5000][currentIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Warning / critical"
|
||||||
|
color: "#252321"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
from: 40
|
||||||
|
to: 99
|
||||||
|
value: root.settings.temperatureWarning
|
||||||
|
editable: true
|
||||||
|
onValueModified: root.settings.setTemperatureWarning(value)
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "/"
|
||||||
|
color: "#7c756c"
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
from: 41
|
||||||
|
to: 110
|
||||||
|
value: root.settings.temperatureCritical
|
||||||
|
editable: true
|
||||||
|
onValueModified: root.settings.setTemperatureCritical(value)
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "°C"
|
||||||
|
color: "#7c756c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: powerColumn.implicitHeight + 24
|
||||||
|
radius: 14
|
||||||
|
color: "#e8f1df"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: powerColumn
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Label {
|
||||||
|
text: "Power profile"
|
||||||
|
color: "#4d7c38"
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.bold: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: PowerProfile.toString(PowerProfiles.profile)
|
||||||
|
color: "#66825a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Button {
|
||||||
|
text: "Saver"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onClicked: PowerProfiles.profile = PowerProfile.PowerSaver
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Balanced"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onClicked: PowerProfiles.profile = PowerProfile.Balanced
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Performance"
|
||||||
|
enabled: PowerProfiles.hasPerformanceProfile
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onClicked: PowerProfiles.profile = PowerProfile.Performance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
fedora/quickshell/scripts/gpu.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
|
||||||
|
if [ -z "$data" ]; then
|
||||||
|
printf '%s\n' '{"text":"N/A"}'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
usage=$(printf '%s\n' "$data" | cut -d',' -f1 | tr -d ' ')
|
||||||
|
temp=$(printf '%s\n' "$data" | cut -d',' -f2 | tr -d ' ')
|
||||||
|
printf '{"text":"%s%% %sC"}\n' "$usage" "$temp"
|
||||||
9
fedora/quickshell/scripts/weather.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
weather=$(curl -4 -sS --connect-timeout 3 --max-time 8 "https://wttr.in/?format=%c%t" 2>/dev/null)
|
||||||
|
if [ -z "$weather" ] || printf '%s' "$weather" | grep -q "Unknown"; then
|
||||||
|
printf '%s\n' '{"text":"N/A"}'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '{"text":"%s"}\n' "$weather"
|
||||||
10
fedora/systemd/user/quickshell-control-center.service
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=QuickShell control center
|
||||||
|
PartOf=niri.service
|
||||||
|
After=niri.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/qs -p %h/.config/quickshell/control-center
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2
|
||||||
|
Environment=QT_QPA_PLATFORM=wayland
|
||||||
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
@@ -1,179 +0,0 @@
|
|||||||
// -*- mode: jsonc -*-
|
|
||||||
{
|
|
||||||
"layer": "top",
|
|
||||||
"height": 32,
|
|
||||||
"spacing": 8,
|
|
||||||
|
|
||||||
"modules-left": [
|
|
||||||
"niri/workspaces"
|
|
||||||
],
|
|
||||||
"modules-center": [
|
|
||||||
"niri/window"
|
|
||||||
],
|
|
||||||
"modules-right": [
|
|
||||||
"privacy",
|
|
||||||
"custom/mail",
|
|
||||||
"custom/weather",
|
|
||||||
"pulseaudio",
|
|
||||||
"network",
|
|
||||||
"niri/language",
|
|
||||||
"power-profiles-daemon",
|
|
||||||
"cpu",
|
|
||||||
"memory",
|
|
||||||
"temperature",
|
|
||||||
"custom/gpu",
|
|
||||||
"disk",
|
|
||||||
"custom/calendar",
|
|
||||||
"tray"
|
|
||||||
],
|
|
||||||
|
|
||||||
"niri/workspaces": {
|
|
||||||
"format": "{index}"
|
|
||||||
},
|
|
||||||
|
|
||||||
"niri/window": {
|
|
||||||
"format": "{}",
|
|
||||||
"max-length": 50,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"niri/language": {
|
|
||||||
"format": "{short}",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"privacy": {
|
|
||||||
"icon-spacing": 4,
|
|
||||||
"icon-size": 16,
|
|
||||||
"transition-duration": 250,
|
|
||||||
"modules": [
|
|
||||||
{ "type": "screenshare" },
|
|
||||||
{ "type": "audio-in" },
|
|
||||||
{ "type": "audio-out" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/mail": {
|
|
||||||
"format": "<span font='Symbols Nerd Font Mono'>{}</span>",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/mail",
|
|
||||||
"interval": 60,
|
|
||||||
"tooltip": true,
|
|
||||||
"on-click": "thunderbird",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/weather": {
|
|
||||||
"format": "{}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/weather.sh",
|
|
||||||
"interval": 900,
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/gpu": {
|
|
||||||
"format": "{}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/gpu.sh",
|
|
||||||
"interval": 5,
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free'></span> {percentage_used}%",
|
|
||||||
"path": "/",
|
|
||||||
"tooltip-format": "{used} / {total} ({percentage_used}%)",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"tray": {
|
|
||||||
"spacing": 10
|
|
||||||
},
|
|
||||||
|
|
||||||
"custom/calendar": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free'></span> {}",
|
|
||||||
"return-type": "json",
|
|
||||||
"exec": "~/.config/waybar/scripts/khal-calendar",
|
|
||||||
"interval": 30,
|
|
||||||
"tooltip": true,
|
|
||||||
"on-click": "alacritty --title khal-popup -e bash -c 'vdirsyncer sync 2>/dev/null; ikhal'",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {usage}%",
|
|
||||||
"tooltip": false,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"memory": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {}%",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"temperature": {
|
|
||||||
"critical-threshold": 80,
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'></span> {temperatureC}°C",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"network": {
|
|
||||||
"format-wifi": "<span font='Symbols Nerd Font Mono'>{icon}</span>",
|
|
||||||
"format-ethernet": "",
|
|
||||||
"format-icons": ["", "", "", "", ""],
|
|
||||||
"tooltip-format-wifi": "{essid} ({signalStrength}%)\n{ipaddr}/{cidr}",
|
|
||||||
"tooltip-format-ethernet": "{ifname}\n{ipaddr}/{cidr}",
|
|
||||||
"format-linked": "{ifname} (No IP) ",
|
|
||||||
"format-disconnected": "<span font='Symbols Nerd Font Mono'></span>",
|
|
||||||
"on-click": "",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"pulseaudio": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'>{icon}</span> {volume}% <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-bluetooth": "<span font='Font Awesome 6 Free Solid'>{icon}</span> {volume}% <span font='Font Awesome 6 Brands'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-bluetooth-muted": "<span font='Font Awesome 6 Free Solid'></span> <span font='Font Awesome 6 Brands'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-muted": "<span font='Font Awesome 6 Free Solid'></span> <span font='Font Awesome 6 Free Solid'></span> {format_source}",
|
|
||||||
"format-source": "{volume}%",
|
|
||||||
"format-source-muted": "<span font='Font Awesome 6 Free Solid'></span>",
|
|
||||||
"format-icons": {
|
|
||||||
"headphone": "",
|
|
||||||
"hands-free": "",
|
|
||||||
"headset": "",
|
|
||||||
"phone": "",
|
|
||||||
"portable": "",
|
|
||||||
"car": "",
|
|
||||||
"default": ["", "", ""]
|
|
||||||
},
|
|
||||||
"on-click": "pavucontrol",
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center"
|
|
||||||
},
|
|
||||||
|
|
||||||
"power-profiles-daemon": {
|
|
||||||
"format": "<span font='Font Awesome 6 Free Solid'>{icon}</span>",
|
|
||||||
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
|
||||||
"tooltip": true,
|
|
||||||
"align": 0.5,
|
|
||||||
"justify": "center",
|
|
||||||
"format-icons": {
|
|
||||||
"default": "",
|
|
||||||
"performance": "",
|
|
||||||
"balanced": "",
|
|
||||||
"power-saver": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
|
|
||||||
if [ -z "$data" ]; then
|
|
||||||
echo '{"text": "GPU N/A", "tooltip": "nvidia-smi not available"}'
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
usage=$(echo "$data" | cut -d',' -f1 | tr -d ' ')
|
|
||||||
temp=$(echo "$data" | cut -d',' -f2 | tr -d ' ')
|
|
||||||
echo "{\"text\": \"GPU ${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
weather=$(curl -s "wttr.in/?format=%c%t" 2>/dev/null)
|
|
||||||
if [ -z "$weather" ] || echo "$weather" | grep -q "Unknown"; then
|
|
||||||
echo '{"text": "N/A", "tooltip": "Weather unavailable"}'
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
tooltip=$(curl -s "wttr.in/?format=%l:+%C+%t+%w+%h" 2>/dev/null)
|
|
||||||
echo "{\"text\": \"${weather}\", \"tooltip\": \"${tooltip}\"}"
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
/* Catppuccin Latte */
|
|
||||||
@define-color rosewater #dc8a78;
|
|
||||||
@define-color flamingo #dd7878;
|
|
||||||
@define-color pink #ea76cb;
|
|
||||||
@define-color mauve #8839ef;
|
|
||||||
@define-color red #d20f39;
|
|
||||||
@define-color maroon #e64553;
|
|
||||||
@define-color peach #fe640b;
|
|
||||||
@define-color yellow #df8e1d;
|
|
||||||
@define-color green #40a02b;
|
|
||||||
@define-color teal #179299;
|
|
||||||
@define-color sky #04a5e5;
|
|
||||||
@define-color sapphire #209fb5;
|
|
||||||
@define-color blue #1e66f5;
|
|
||||||
@define-color lavender #7287fd;
|
|
||||||
@define-color text #4c4f69;
|
|
||||||
@define-color subtext1 #5c5f77;
|
|
||||||
@define-color subtext0 #6c6f85;
|
|
||||||
@define-color overlay2 #7c7f93;
|
|
||||||
@define-color overlay1 #8c8fa1;
|
|
||||||
@define-color overlay0 #9ca0b0;
|
|
||||||
@define-color surface2 #acb0be;
|
|
||||||
@define-color surface1 #bcc0cc;
|
|
||||||
@define-color surface0 #ccd0da;
|
|
||||||
@define-color base #eff1f5;
|
|
||||||
@define-color mantle #e6e9ef;
|
|
||||||
@define-color crust #dce0e8;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-family: 'Noto Sans Mono', 'Symbols Nerd Font Mono', 'Symbols Nerd Font', 'Font Awesome 6 Free', monospace;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar {
|
|
||||||
background-color: rgba(30, 30, 46, 0.72);
|
|
||||||
color: @text;
|
|
||||||
transition-property: background-color;
|
|
||||||
transition-duration: .5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
window#waybar.hidden {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
box-shadow: inset 0 -3px transparent;
|
|
||||||
border: none;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background: inherit;
|
|
||||||
box-shadow: inset 0 -2px @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Workspaces */
|
|
||||||
#workspaces button {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background-color: #000000;
|
|
||||||
color: @overlay2;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button:hover {
|
|
||||||
background: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.active {
|
|
||||||
color: @blue;
|
|
||||||
box-shadow: inset 0 -2px @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button.urgent {
|
|
||||||
background-color: #000000;
|
|
||||||
color: @base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Common module styling */
|
|
||||||
#window,
|
|
||||||
#custom-calendar,
|
|
||||||
#cpu,
|
|
||||||
#memory,
|
|
||||||
#disk,
|
|
||||||
#temperature,
|
|
||||||
#network,
|
|
||||||
#pulseaudio,
|
|
||||||
#wireplumber,
|
|
||||||
#tray,
|
|
||||||
#power-profiles-daemon,
|
|
||||||
#language,
|
|
||||||
#custom-gpu,
|
|
||||||
#custom-weather,
|
|
||||||
#privacy {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background-color: #000000;
|
|
||||||
border-radius: 16px;
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
#workspaces button label,
|
|
||||||
#window label,
|
|
||||||
#custom-calendar label,
|
|
||||||
#cpu label,
|
|
||||||
#memory label,
|
|
||||||
#disk label,
|
|
||||||
#temperature label,
|
|
||||||
#network label,
|
|
||||||
#pulseaudio label,
|
|
||||||
#wireplumber label,
|
|
||||||
#tray label,
|
|
||||||
#power-profiles-daemon label,
|
|
||||||
#language label,
|
|
||||||
#custom-gpu label,
|
|
||||||
#custom-weather label,
|
|
||||||
#privacy label {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#window,
|
|
||||||
#workspaces {
|
|
||||||
margin: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#window {
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calendar/Clock */
|
|
||||||
#custom-calendar {
|
|
||||||
color: @blue;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CPU */
|
|
||||||
#cpu {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory */
|
|
||||||
#memory {
|
|
||||||
color: @mauve;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Temperature */
|
|
||||||
#temperature {
|
|
||||||
color: @peach;
|
|
||||||
}
|
|
||||||
|
|
||||||
#temperature.critical {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Network */
|
|
||||||
#network {
|
|
||||||
color: @sapphire;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#network.disconnected {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pulseaudio */
|
|
||||||
#pulseaudio {
|
|
||||||
color: @yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pulseaudio.muted {
|
|
||||||
color: @overlay1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Language */
|
|
||||||
#language {
|
|
||||||
color: @teal;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Power profiles */
|
|
||||||
#power-profiles-daemon {
|
|
||||||
color: @subtext0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.performance {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.balanced {
|
|
||||||
color: @blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#power-profiles-daemon.power-saver {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mail */
|
|
||||||
#custom-mail {
|
|
||||||
color: @lavender;
|
|
||||||
}
|
|
||||||
|
|
||||||
#custom-mail.unread {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disk */
|
|
||||||
#disk {
|
|
||||||
color: @flamingo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GPU */
|
|
||||||
#custom-gpu {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Weather */
|
|
||||||
#custom-weather {
|
|
||||||
color: @sky;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Privacy */
|
|
||||||
#privacy {
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item {
|
|
||||||
min-height: 24px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
color: @base;
|
|
||||||
background-color: #000000;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.screenshare {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.audio-in {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#privacy-item.audio-out {
|
|
||||||
background-color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tray */
|
|
||||||
#tray {
|
|
||||||
color: @text;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray > .passive {
|
|
||||||
-gtk-icon-effect: dim;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tray > .needs-attention {
|
|
||||||
-gtk-icon-effect: highlight;
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
39
install.sh
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
REPO_ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
FEDORA_ROOT="$REPO_ROOT/fedora"
|
||||||
|
CONFIG_ROOT="$HOME/.config"
|
||||||
|
LOCAL_BIN="$HOME/.local/bin"
|
||||||
|
|
||||||
|
link_config() {
|
||||||
|
local source=$1
|
||||||
|
local destination=$2
|
||||||
|
|
||||||
|
mkdir -p "$(dirname -- "$destination")"
|
||||||
|
if [[ -e "$destination" && ! -L "$destination" ]]; then
|
||||||
|
printf 'Refusing to replace existing path: %s\n' "$destination" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ln -sfn -- "$source" "$destination"
|
||||||
|
}
|
||||||
|
|
||||||
|
for name in niri fuzzel alacritty btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do
|
||||||
|
link_config "$FEDORA_ROOT/$name" "$CONFIG_ROOT/$name"
|
||||||
|
done
|
||||||
|
|
||||||
|
link_config "$REPO_ROOT/nvim" "$CONFIG_ROOT/nvim"
|
||||||
|
link_config "$FEDORA_ROOT/quickshell/control-center" "$CONFIG_ROOT/quickshell/control-center"
|
||||||
|
link_config "$FEDORA_ROOT/systemd/user/quickshell-control-center.service" \
|
||||||
|
"$CONFIG_ROOT/systemd/user/quickshell-control-center.service"
|
||||||
|
link_config "$FEDORA_ROOT/wallpapers/wallpaper.png" "$CONFIG_ROOT/wallpaper.png"
|
||||||
|
|
||||||
|
mkdir -p "$LOCAL_BIN"
|
||||||
|
|
||||||
|
for project in khal-calendar mail-counter; do
|
||||||
|
cargo build --release --manifest-path "$FEDORA_ROOT/$project/Cargo.toml"
|
||||||
|
install -m 755 "$FEDORA_ROOT/$project/target/release/$project" "$LOCAL_BIN/$project"
|
||||||
|
done
|
||||||
|
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
printf 'Installed Fedora and Neovim links; Rust binaries are in %s.\n' "$LOCAL_BIN"
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
{
|
{
|
||||||
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
|
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
|
||||||
"LuaSnip": { "branch": "master", "commit": "dae4f5aaa3574bd0c2b9dd20fb9542a02c10471c" },
|
"LuaSnip": { "branch": "master", "commit": "0abc8f390b278c3b4aabc4c004ac8a088b65cf24" },
|
||||||
"alabaster.nvim": { "branch": "main", "commit": "ae0c5f41c70b576f0678319e57fe47b2b288d2fc" },
|
"alabaster.nvim": { "branch": "main", "commit": "b902c73fabefc13583bfc0c18b28950ea8f6244f" },
|
||||||
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
|
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
|
||||||
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
|
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
|
||||||
"cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" },
|
"cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" },
|
||||||
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
|
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
|
||||||
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
|
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
|
||||||
"crates.nvim": { "branch": "main", "commit": "ac9fa498a9edb96dc3056724ff69d5f40b898453" },
|
"crates.nvim": { "branch": "main", "commit": "694357861ec9ebf12475ddcdd04ea45a0923c32d" },
|
||||||
"gitsigns.nvim": { "branch": "main", "commit": "9f3c6dd7868bcc116e9c1c1929ce063b978fa519" },
|
"gitsigns.nvim": { "branch": "main", "commit": "eb60cc7b94c46005237fd34170d76f3a089a90aa" },
|
||||||
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
|
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||||
"lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" },
|
"lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" },
|
||||||
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
|
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
|
||||||
"mason-lspconfig.nvim": { "branch": "main", "commit": "6c4830e37743b060d13c9269394176aea6a0fbc8" },
|
"mason-lspconfig.nvim": { "branch": "main", "commit": "a4068c3ebd4cb335b25239e5ea35c22ee6007962" },
|
||||||
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
|
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
|
||||||
"neo-tree.nvim": { "branch": "v3.x", "commit": "f3df514fff2bdd4318127c40470984137f87b62e" },
|
"neo-tree.nvim": { "branch": "v3.x", "commit": "ebd66767191714e008ce73b769518a763ff31bdc" },
|
||||||
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
|
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
|
||||||
"nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" },
|
"nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" },
|
||||||
"nvim-cmp": { "branch": "main", "commit": "da88697d7f45d16852c6b2769dc52387d1ddc45f" },
|
"nvim-cmp": { "branch": "main", "commit": "2ffe79f1f021def8dd1fcd81deb16f1bb0d989f3" },
|
||||||
"nvim-lspconfig": { "branch": "master", "commit": "5a855bcfec7973767a1a472335684bbd71d2fa2b" },
|
"nvim-lspconfig": { "branch": "master", "commit": "d5b6e3db4c17b0146f63a2fc47e2027a754b2cb1" },
|
||||||
"nvim-treesitter": { "branch": "main", "commit": "dc42c209f3820bdfaae0956f15de29689aa6b451" },
|
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
|
||||||
"nvim-web-devicons": { "branch": "master", "commit": "746ffbb17975ebd6c40142362eee1b0249969c5c" },
|
"nvim-web-devicons": { "branch": "master", "commit": "09d1324e264c6950262dbe02a9bce2933a6800db" },
|
||||||
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
|
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
|
||||||
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
|
||||||
"rustaceanvim": { "branch": "master", "commit": "e9c5aaba16fead831379d5f44617547a90b913c7" },
|
"rustaceanvim": { "branch": "main", "commit": "e9c5aaba16fead831379d5f44617547a90b913c7" },
|
||||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" },
|
"telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" },
|
||||||
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
||||||
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
|
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
|
||||||
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
||||||
|
|||||||
@@ -4,5 +4,28 @@ return {
|
|||||||
config = function()
|
config = function()
|
||||||
vim.o.background = "light"
|
vim.o.background = "light"
|
||||||
vim.cmd.colorscheme("alabaster")
|
vim.cmd.colorscheme("alabaster")
|
||||||
|
|
||||||
|
for _, group in ipairs({
|
||||||
|
"Normal",
|
||||||
|
"NormalNC",
|
||||||
|
"NormalFloat",
|
||||||
|
"FloatBorder",
|
||||||
|
"SignColumn",
|
||||||
|
"FoldColumn",
|
||||||
|
"EndOfBuffer",
|
||||||
|
"LineNr",
|
||||||
|
"CursorLineNr",
|
||||||
|
"StatusLine",
|
||||||
|
"StatusLineNC",
|
||||||
|
"TabLine",
|
||||||
|
"TabLineFill",
|
||||||
|
"TabLineSel",
|
||||||
|
"NeoTreeNormal",
|
||||||
|
"NeoTreeNormalNC",
|
||||||
|
"NeoTreeEndOfBuffer",
|
||||||
|
"BufferLineFill",
|
||||||
|
}) do
|
||||||
|
vim.api.nvim_set_hl(0, group, { bg = "none" })
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
local layout = "EN"
|
local layout = "EN"
|
||||||
|
local has_im_select = vim.fn.executable("im-select") == 1
|
||||||
|
|
||||||
local function update_layout()
|
local function update_layout()
|
||||||
|
if not has_im_select then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
vim.system({ "im-select" }, { text = true }, function(result)
|
vim.system({ "im-select" }, { text = true }, function(result)
|
||||||
if result.stdout then
|
if result.stdout then
|
||||||
layout = result.stdout:find("Russian") and "RU" or "EN"
|
layout = result.stdout:find("Russian") and "RU" or "EN"
|
||||||
@@ -10,7 +15,9 @@ end
|
|||||||
|
|
||||||
-- Update layout in background every second, never blocks UI
|
-- Update layout in background every second, never blocks UI
|
||||||
local timer = vim.loop.new_timer()
|
local timer = vim.loop.new_timer()
|
||||||
|
if has_im_select then
|
||||||
timer:start(0, 1000, vim.schedule_wrap(update_layout))
|
timer:start(0, 1000, vim.schedule_wrap(update_layout))
|
||||||
|
end
|
||||||
|
|
||||||
local function keyboard_layout()
|
local function keyboard_layout()
|
||||||
return layout
|
return layout
|
||||||
|
|||||||