fixes
This commit is contained in:
BIN
bazzite/.DS_Store
vendored
Normal file
BIN
bazzite/.DS_Store
vendored
Normal file
Binary file not shown.
113
bazzite/README.md
Normal file
113
bazzite/README.md
Normal 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
1
bazzite/khal-calendar/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
383
bazzite/khal-calendar/Cargo.lock
generated
Normal file
383
bazzite/khal-calendar/Cargo.lock
generated
Normal 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"
|
||||
15
bazzite/khal-calendar/Cargo.toml
Normal file
15
bazzite/khal-calendar/Cargo.toml
Normal 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"
|
||||
18
bazzite/khal-calendar/README.md
Normal file
18
bazzite/khal-calendar/README.md
Normal 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"
|
||||
```
|
||||
160
bazzite/khal-calendar/src/main.rs
Normal file
160
bazzite/khal-calendar/src/main.rs
Normal 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
1
bazzite/mail-counter/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
213
bazzite/mail-counter/Cargo.lock
generated
Normal file
213
bazzite/mail-counter/Cargo.lock
generated
Normal 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"
|
||||
15
bazzite/mail-counter/Cargo.toml
Normal file
15
bazzite/mail-counter/Cargo.toml
Normal 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"
|
||||
18
bazzite/mail-counter/README.md
Normal file
18
bazzite/mail-counter/README.md
Normal 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"
|
||||
```
|
||||
113
bazzite/mail-counter/src/main.rs
Normal file
113
bazzite/mail-counter/src/main.rs
Normal 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)));
|
||||
}
|
||||
@@ -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
|
||||
|
||||
BIN
bazzite/screenshots/waybar-icons-fixed.png
Normal file
BIN
bazzite/screenshots/waybar-icons-fixed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 MiB |
BIN
bazzite/wallpapers/image.png
Normal file
BIN
bazzite/wallpapers/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 804 KiB |
BIN
bazzite/wallpapers/raspberry.png
Normal file
BIN
bazzite/wallpapers/raspberry.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -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
4
bazzite/waybar/scripts/gpu.sh
Normal file → Executable 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\": \"\"}"
|
||||
|
||||
@@ -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
0
bazzite/waybar/scripts/weather.sh
Normal file → Executable 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 */
|
||||
|
||||
Reference in New Issue
Block a user