This commit is contained in:
Mikhail Kilin
2026-06-21 16:22:06 +03:00
parent 698c953c55
commit 8cedd606f5
58 changed files with 4333 additions and 146 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.serena/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/cache
/project.local.yml

132
.serena/project.yml Normal file
View File

@@ -0,0 +1,132 @@
# the name by which the project can be referenced within Serena
project_name: "dotfiles"
# list of languages for which language servers are started; choose from:
# al angular ansible bash clojure
# cpp cpp_ccls crystal csharp csharp_omnisharp
# dart elixir elm erlang fortran
# fsharp go groovy haskell haxe
# hlsl html java json julia
# kotlin lean4 lua luau markdown
# matlab msl nix ocaml pascal
# perl php php_phpactor powershell python
# python_jedi python_ty r rego ruby
# ruby_solargraph rust scala scss solidity
# swift systemverilog terraform toml typescript
# typescript_vts vue yaml zig
# (This list may be outdated. 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 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
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
encoding: "utf-8"
# line ending convention to use when writing source files.
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
line_ending:
# The language backend to use for this project.
# If not set, the global setting from serena_config.yml is used.
# Valid values: LSP, JetBrains
# Note: the backend is fixed at startup. If a project with a different backend
# is activated post-init, an error will be returned.
language_backend:
# whether to use project's .gitignore files to ignore files
ignore_all_files_in_gitignore: true
# advanced configuration option allowing to configure language server-specific options.
# Maps the language key to the options.
# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
# No documentation on options means no options are available.
ls_specific_settings: {}
# list of additional paths to ignore in this project.
# Same syntax as gitignore, so you can use * and **.
# Note: global ignored_paths from serena_config.yml are also applied additively.
ignored_paths: []
# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false
# list of tool names to exclude.
# This extends the existing exclusions (e.g. from the global configuration)
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
# This extends the existing inclusions (e.g. from the global configuration).
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
included_optional_tools: []
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
fixed_tools: []
# list of mode names that are to be activated by default, overriding the setting in the global configuration.
# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply
# for this project.
# This setting can, in turn, be overridden by CLI parameters (--mode).
# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
default_modes:
# list of mode names to be activated additionally for this project, e.g. ["query-projects"]
# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
added_modes:
# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""
# time budget (seconds) per tool call for the retrieval of additional symbol information
# such as docstrings or parameter information.
# This overrides the corresponding setting in the global configuration; see the documentation there.
# If null or missing, use the setting from the global configuration.
symbol_info_budget:
# list of regex patterns which, when matched, mark a memory entry as readonly.
# Extends the list from the global configuration, merging the two lists.
read_only_memory_patterns: []
# list of regex patterns for memories to completely ignore.
# Matching memories will not appear in list_memories or activate_project output
# and cannot be accessed via read_memory or write_memory.
# To access ignored memory files, use the read_file tool on the raw file path.
# Extends the list from the global configuration, merging the two lists.
# Example: ["_archive/.*", "_episodes/.*"]
ignored_memory_patterns: []
# list of additional workspace folder paths for cross-package reference support (e.g. in monorepos).
# Paths can be absolute or relative to the project root.
# Each folder is registered as an LSP workspace folder, enabling language servers to discover
# symbols and references across package boundaries.
# Currently supported for: TypeScript.
# Example:
# additional_workspace_folders:
# - ../sibling-package
# - ../shared-lib
additional_workspace_folders: []

87
AGENT.md Normal file
View File

@@ -0,0 +1,87 @@
# 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 без явного запроса.

BIN
bazzite/.DS_Store vendored Normal file

Binary file not shown.

113
bazzite/README.md Normal file
View File

@@ -0,0 +1,113 @@
# Конфиги рабочего стола 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
bazzite/khal-calendar/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

383
bazzite/khal-calendar/Cargo.lock generated Normal file
View File

@@ -0,0 +1,383 @@
# 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"

View File

@@ -0,0 +1,15 @@
[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"

View File

@@ -0,0 +1,18 @@
# 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"
```

View File

@@ -0,0 +1,160 @@
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 Normal file
View File

@@ -0,0 +1 @@
/target/

213
bazzite/mail-counter/Cargo.lock generated Normal file
View File

@@ -0,0 +1,213 @@
# 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"

View File

@@ -0,0 +1,15 @@
[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"

View File

@@ -0,0 +1,18 @@
# 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"
```

View File

@@ -0,0 +1,113 @@
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)));
}

View File

@@ -145,6 +145,7 @@ environment {
}
// 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
@@ -365,6 +366,14 @@ window-rule {
// 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -13,18 +13,17 @@
"modules-right": [
"privacy",
"custom/mail",
"idle_inhibitor",
"custom/weather",
"pulseaudio",
"network",
"niri/language",
"power-profiles-daemon",
"cpu",
"memory",
"temperature",
"custom/gpu",
"disk",
"niri/language",
"clock",
"custom/calendar",
"tray"
],
@@ -34,11 +33,15 @@
"niri/window": {
"format": "{}",
"max-length": 50
"max-length": 50,
"align": 0.5,
"justify": "center"
},
"niri/language": {
"format": "{short}"
"format": "{short}",
"align": 0.5,
"justify": "center"
},
"privacy": {
@@ -53,20 +56,14 @@
},
"custom/mail": {
"format": "{}",
"format": "<span font='Symbols Nerd Font Mono'>{}</span>",
"return-type": "json",
"exec": "python3 ~/.config/waybar/scripts/mail.py",
"exec": "~/.config/waybar/scripts/mail",
"interval": 60,
"tooltip": true,
"on-click": "flatpak run org.mozilla.Thunderbird"
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "",
"deactivated": ""
}
"on-click": "flatpak run org.mozilla.Thunderbird",
"align": 0.5,
"justify": "center"
},
"custom/weather": {
@@ -74,87 +71,109 @@
"return-type": "json",
"exec": "~/.config/waybar/scripts/weather.sh",
"interval": 900,
"tooltip": true
"tooltip": true,
"align": 0.5,
"justify": "center"
},
"custom/gpu": {
"format": " {}",
"format": "{}",
"return-type": "json",
"exec": "~/.config/waybar/scripts/gpu.sh",
"interval": 5,
"tooltip": true
"tooltip": true,
"align": 0.5,
"justify": "center"
},
"disk": {
"format": "{percentage_used}% ",
"format": "<span font='Font Awesome 6 Free'></span> {percentage_used}%",
"path": "/",
"tooltip-format": "{used} / {total} ({percentage_used}%)"
"tooltip-format": "{used} / {total} ({percentage_used}%)",
"align": 0.5,
"justify": "center"
},
"tray": {
"spacing": 10
},
"clock": {
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
"format": "{:%H:%M}",
"format-alt": "{:%Y-%m-%d}"
"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": "{usage}% ",
"tooltip": false
"format": "<span font='Font Awesome 6 Free Solid'></span> {usage}%",
"tooltip": false,
"align": 0.5,
"justify": "center"
},
"memory": {
"format": "{}% "
"format": "<span font='Font Awesome 6 Free Solid'></span> {}%",
"align": 0.5,
"justify": "center"
},
"temperature": {
"critical-threshold": 80,
"format": "{temperatureC}°C {icon}",
"format-icons": ["", "", ""]
"format": "<span font='Font Awesome 6 Free Solid'></span> {temperatureC}°C",
"align": 0.5,
"justify": "center"
},
"network": {
"format-wifi": "{icon}",
"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": "󰤭",
"on-click": ""
"format-disconnected": "<span font='Symbols Nerd Font Mono'>󰤭</span>",
"on-click": "",
"align": 0.5,
"justify": "center"
},
"pulseaudio": {
"format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon} {format_source}",
"format-bluetooth-muted": " {icon} {format_source}",
"format-muted": " {format_source}",
"format-source": "{volume}% ",
"format-source-muted": "",
"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": ["", "", ""]
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
},
"on-click": "pavucontrol"
"on-click": "pavucontrol",
"align": 0.5,
"justify": "center"
},
"power-profiles-daemon": {
"format": "{icon}",
"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": ""
"default": "",
"performance": "",
"balanced": "",
"power-saver": ""
}
}
}

4
bazzite/waybar/scripts/gpu.sh Normal file → Executable file
View File

@@ -1,9 +1,9 @@
#!/bin/bash
data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
if [ -z "$data" ]; then
echo '{"text": "N/A", "tooltip": "nvidia-smi not available"}'
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\": \"${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}"
echo "{\"text\": \"GPU ${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}"

View File

@@ -1,45 +0,0 @@
#!/usr/bin/env python3
import glob
import json
import sqlite3
import os
profile_dirs = glob.glob(
os.path.expanduser("~/.var/app/org.mozilla.Thunderbird/.thunderbird/*.default-esr")
) or glob.glob(
os.path.expanduser("~/.thunderbird/*.default-esr")
)
if not profile_dirs:
print(json.dumps({"text": "", "tooltip": "No Thunderbird profile found"}))
exit()
db_path = os.path.join(profile_dirs[0], "global-messages-db.sqlite")
if not os.path.exists(db_path):
print(json.dumps({"text": "", "tooltip": "No message database"}))
exit()
try:
conn = sqlite3.connect(f"file:{db_path}?mode=ro&nolock=1", uri=True)
cursor = conn.cursor()
cursor.execute(
"SELECT COUNT(*) FROM messages WHERE jsonAttributes LIKE '%\"read\":false%' OR jsonAttributes LIKE '%\"read\": false%'"
)
count = cursor.fetchone()[0]
conn.close()
except Exception:
# fallback: try folderStatus
try:
conn = sqlite3.connect(f"file:{db_path}?mode=ro&nolock=1", uri=True)
cursor = conn.cursor()
cursor.execute("SELECT SUM(numNewMessages) FROM folderlocations WHERE numNewMessages > 0")
row = cursor.fetchone()
count = row[0] if row and row[0] else 0
conn.close()
except Exception:
count = 0
if count > 0:
print(json.dumps({"text": f"󰇮 {count}", "tooltip": f"{count} unread emails", "class": "unread"}))
else:
print(json.dumps({"text": "󰇮", "tooltip": "No unread emails"}))

0
bazzite/waybar/scripts/weather.sh Normal file → Executable file
View File

View File

@@ -27,13 +27,13 @@
@define-color crust #dce0e8;
* {
font-family: 'JetBrainsMono Nerd Font', 'Noto Sans Mono', monospace;
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: #1e1e2e;
background-color: rgba(30, 30, 46, 0.72);
color: @text;
transition-property: background-color;
transition-duration: .5s;
@@ -46,7 +46,7 @@ window#waybar.hidden {
button {
box-shadow: inset 0 -3px transparent;
border: none;
border-radius: 0;
border-radius: 16px;
}
button:hover {
@@ -56,27 +56,30 @@ button:hover {
/* Workspaces */
#workspaces button {
padding: 0 6px;
background-color: transparent;
color: #a6adc8;
min-height: 24px;
padding: 4px 8px;
background-color: #000000;
color: @overlay2;
border-radius: 16px;
}
#workspaces button:hover {
background: alpha(@surface0, 0.5);
background: #000000;
}
#workspaces button.active {
color: #cdd6f4;
color: @blue;
box-shadow: inset 0 -2px @blue;
}
#workspaces button.urgent {
background-color: alpha(@red, 0.2);
color: @red;
background-color: #000000;
color: @base;
}
/* Common module styling */
#clock,
#window,
#custom-calendar,
#cpu,
#memory,
#disk,
@@ -85,27 +88,50 @@ button:hover {
#pulseaudio,
#wireplumber,
#tray,
#idle_inhibitor,
#power-profiles-daemon,
#language,
#custom-gpu,
#custom-weather,
#privacy {
padding: 0 10px;
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: #cdd6f4;
color: @text;
}
/* Clock */
#clock {
/* Calendar/Clock */
#custom-calendar {
color: @blue;
font-weight: bold;
}
@@ -154,15 +180,6 @@ button:hover {
font-weight: bold;
}
/* Idle inhibitor */
#idle_inhibitor {
color: @overlay1;
}
#idle_inhibitor.activated {
color: @peach;
}
/* Power profiles */
#power-profiles-daemon {
color: @subtext0;
@@ -206,24 +223,28 @@ button:hover {
/* Privacy */
#privacy {
background-color: transparent;
padding: 0;
}
#privacy-item {
padding: 0 5px;
min-height: 24px;
padding: 4px 8px;
color: @base;
background-color: #000000;
border-radius: 16px;
}
#privacy-item.screenshare {
background-color: @peach;
background-color: #000000;
}
#privacy-item.audio-in {
background-color: @red;
background-color: #000000;
}
#privacy-item.audio-out {
background-color: @blue;
background-color: #000000;
}
/* Tray */

89
fedora/README.md Normal file
View File

@@ -0,0 +1,89 @@
# Конфиги рабочего стола 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. |
| `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-сессию.

View File

@@ -0,0 +1,281 @@
[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/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/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/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/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/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/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/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/steam steam://open/settings
[Desktop Action BigPicture]
Name=Big Picture
Exec=/usr/bin/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/steam steam://open/friends

257
fedora/btop/btop.conf Normal file
View File

@@ -0,0 +1,257 @@
#? 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 = ""

View File

@@ -0,0 +1 @@
GSK_RENDERER=gl

18
fedora/fuzzel/fuzzel.ini Normal file
View File

@@ -0,0 +1,18 @@
# 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

10
fedora/glow/glow.yml Normal file
View File

@@ -0,0 +1,10 @@
# 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

84
fedora/gtk-3.0/colors.css Normal file
View File

@@ -0,0 +1,84 @@
@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
fedora/gtk-3.0/gtk.css Normal file
View File

@@ -0,0 +1 @@
@import 'colors.css';

View File

@@ -0,0 +1,17 @@
[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

84
fedora/gtk-4.0/colors.css Normal file
View File

@@ -0,0 +1,84 @@
@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;

2
fedora/gtk-4.0/gtk.css Normal file
View File

@@ -0,0 +1,2 @@
@import 'colors.css';
@import 'kde_window_geometry.css';

View File

@@ -0,0 +1,14 @@
[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
fedora/khal-calendar/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

383
fedora/khal-calendar/Cargo.lock generated Normal file
View File

@@ -0,0 +1,383 @@
# 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"

View File

@@ -0,0 +1,15 @@
[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"

View File

@@ -0,0 +1,18 @@
# 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"
```

View File

@@ -0,0 +1,160 @@
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
fedora/mail-counter/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

213
fedora/mail-counter/Cargo.lock generated Normal file
View File

@@ -0,0 +1,213 @@
# 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"

View File

@@ -0,0 +1,15 @@
[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"

View File

@@ -0,0 +1,18 @@
# 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"
```

View File

@@ -0,0 +1,113 @@
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)));
}

626
fedora/niri/config.kdl Normal file
View File

@@ -0,0 +1,626 @@
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 swaybg -i ~/Pictures/Wallpapers/raspberry.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-1"
}
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" "env DISPLAY=:0 xsel -ob | wl-copy"; }
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 || 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" "mpv --pause \"$(wl-paste)\""; }
// refresh.sh was a local Bazzite helper; keep these disabled until a Fedora helper exists.
// 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; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

179
fedora/waybar/config.jsonc Normal file
View File

@@ -0,0 +1,179 @@
// -*- 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": ""
}
}
}

9
fedora/waybar/scripts/gpu.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/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\": \"\"}"

View File

@@ -0,0 +1,8 @@
#!/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}\"}"

262
fedora/waybar/style.css Normal file
View File

@@ -0,0 +1,262 @@
/* 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;
}

View File

@@ -0,0 +1,17 @@
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"

View File

@@ -18,7 +18,16 @@ map("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "Increase window width
-- Buffers
map("n", "<S-l>", ":bnext<CR>", { desc = "Next buffer" })
map("n", "<S-h>", ":bprevious<CR>", { desc = "Previous buffer" })
map("n", "<leader>bd", ":bdelete<CR>", { desc = "Delete buffer" })
map("n", "<leader>bd", function()
local current = vim.api.nvim_get_current_buf()
local bufs = vim.tbl_filter(function(b)
return b.bufnr ~= current and vim.bo[b.bufnr].filetype ~= "neo-tree"
end, vim.fn.getbufinfo({ buflisted = 1 }))
if #bufs > 0 then
vim.api.nvim_set_current_buf(bufs[1].bufnr)
end
vim.cmd("bdelete " .. current)
end, { desc = "Delete buffer" })
-- Move lines up/down in visual mode
map("v", "J", ":m '>+1<CR>gv=gv", { desc = "Move selection down" })

View File

@@ -47,6 +47,14 @@ return {
{ "<leader>n", "<cmd>Neotree toggle<cr>", desc = "Toggle file explorer" },
},
opts = {
window = {
mappings = {
["l"] = "open",
["h"] = "close_node",
["<right>"] = "open",
["<left>"] = "close_node",
},
},
filesystem = {
filtered_items = {
visible = true,

View File

@@ -1,24 +1,23 @@
local layout = "EN"
local function update_layout()
vim.system({ "im-select" }, { text = true }, function(result)
if result.stdout then
layout = result.stdout:find("Russian") and "RU" or "EN"
end
end)
end
-- Update layout in background every second, never blocks UI
local timer = vim.loop.new_timer()
timer:start(0, 1000, vim.schedule_wrap(update_layout))
local function keyboard_layout()
local handle = io.popen("im-select")
if not handle then
return ""
end
local result = handle:read("*a")
handle:close()
if result:find("Russian") then
return "RU"
end
return "EN"
return layout
end
local function keyboard_layout_color()
local handle = io.popen("im-select")
if not handle then
return { bg = "#a6e3a1", fg = "#1e1e2e", gui = "bold" }
end
local result = handle:read("*a")
handle:close()
if result:find("Russian") then
if layout == "RU" then
return { bg = "#f38ba8", fg = "#1e1e2e", gui = "bold" }
end
return { bg = "#a6e3a1", fg = "#1e1e2e", gui = "bold" }