diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ebd202e..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 1fce277..bf89ecd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ plugin/ .claude/ +.DS_Store +*.log +target/ diff --git a/.serena/project.yml b/.serena/project.yml index 7f18be3..1eccc28 100644 --- a/.serena/project.yml +++ b/.serena/project.yml @@ -1,41 +1,6 @@ # the name by which the project can be referenced within Serena/when chatting with the LLM. project_name: "dotfiles" -# list of languages for which language servers are started (LSP backend only); choose from: -# ada al angular ansible bash -# bsl clojure cpp cpp_ccls crystal -# csharp csharp_omnisharp cue dart elixir -# elm erlang fortran fsharp gdscript -# go groovy haskell haxe hlsl -# html java json julia kotlin -# latex lean4 lua luau markdown -# matlab msl nix ocaml pascal -# perl php php_phpactor php_phpantom powershell -# python python_jedi python_pyrefly python_ty r -# rego ruby ruby_solargraph rust scala -# scss solidity svelte swift systemverilog -# terraform toml typescript typescript_vts vue -# yaml zig -# (This list may be outdated; generated with scripts/print_language_list.py; -# For the current list, see values of Language enum here: -# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py) -# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) -# Note: -# - For C, use cpp -# - For JavaScript, use typescript -# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root) -# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm) -# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) -# - For Free Pascal/Lazarus, use pascal -# Special requirements: -# Some languages require additional setup/installations. -# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers -# When using multiple languages, the first language server that supports a given file will be used for that file. -# The first language is the default language and the respective language server will be used as a fallback. -# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. -languages: -- lua - # the encoding used by text files in the project # For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings encoding: "utf-8" @@ -63,6 +28,13 @@ ls_specific_settings: {} # list of additional paths to ignore in this project. # Same syntax as gitignore, so you can use * and **. +# Important: quote patterns that start with `*`, otherwise YAML treats them as aliases. +# Example: +# ignored_paths: +# - "examples/**" +# - ".worktrees/**" +# - "**/bin/**" +# - "**/obj/**" # Note: global ignored_paths from serena_config.yml are also applied additively. ignored_paths: [] @@ -158,3 +130,38 @@ ls_additional_workspace_folders: [] # - "./subproject2" ls_workspace_folders: - . + +# list of language servers to start when using the LSP backend; choose from: +# ada al angular ansible bash +# bsl clojure cpp cpp_ccls crystal +# csharp csharp_omnisharp cue dart elixir +# elm erlang fortran fsharp gdscript +# go groovy haskell haxe hlsl +# html java json julia kotlin +# latex lean4 lua luau markdown +# matlab msl nix ocaml pascal +# perl php php_phpactor php_phpantom powershell +# python python_jedi python_pyrefly python_ty r +# rego ruby ruby_solargraph rust scala +# scss solidity svelte swift systemverilog +# terraform toml typescript typescript_vts vue +# yaml zig +# (This list may be outdated; generated with scripts/print_language_list.py; +# For the current list, see values of Language enum here: +# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py) +# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# Note: +# - For C, use cpp +# - For JavaScript, use typescript +# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root) +# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm) +# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) +# - For Free Pascal/Lazarus, use pascal +# Special requirements: +# Some language servers require additional setup/installations. +# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers +# When using multiple language servers, the first language server that supports a given file will be used for that file. +# The first language server is the default language and the respective language server will be used as a fallback. +# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. +language_servers: +- lua diff --git a/AGENT.md b/AGENT.md deleted file mode 100644 index 49ee78d..0000000 --- a/AGENT.md +++ /dev/null @@ -1,87 +0,0 @@ -# AGENT.md - -## Про что этот репозиторий - -`dotfiles` - личный репозиторий конфигураций для двух разных зон: - -- `nvim/` - конфиг Neovim для основной development-среды. -- `fedora/` - текущий основной профиль рабочего стола Fedora с Niri. -- `bazzite/` - старый профиль Bazzite/Niri, который теперь нужен в основном как - legacy reference для миграции, сравнения и поддержки старых машин. - -`CLAUDE.md` в этом репозитории покрывает в основном Neovim. Для desktop-задач -он не является полной картой проекта, поэтому сначала ориентируйся по -`README.md`, а затем по `fedora/README.md` или `bazzite/README.md`. - -## Верхнеуровневая структура - -- `README.md` - общий вход в репозиторий и краткая карта текущей структуры. -- `CLAUDE.md` - узкий guide по `nvim/`. -- `nvim/` - Neovim config: - - `init.lua` - точка входа; - - `lua/config/` - базовые options, keymaps, autocmds; - - `lua/plugins/` - конфиги плагинов; - - `lazy-lock.json` - зафиксированные версии плагинов. -- `fedora/` - основной desktop profile: - - `README.md` - каноническое описание профиля; - - `niri/config.kdl` - compositor/session behavior; - - `waybar/config.jsonc` и `waybar/style.css` - панель и стили; - - `khal-calendar/` и `mail-counter/` - Rust-модули для Waybar. -- `bazzite/` - legacy profile со структурой, близкой к `fedora/`. - -Скрытые каталоги вроде `.git`, `.claude`, `.serena` считай tooling/infrastructure -metadata, а не рабочей частью конфигурации. - -## Что читать для контекста - -Всегда начинай с `README.md`. - -Дальше маршрут такой: - -- Если задача про Neovim: - 1. `CLAUDE.md` - 2. `nvim/init.lua` - 3. нужные файлы из `nvim/lua/config/` или `nvim/lua/plugins/` - -- Если задача про текущую Fedora-машину, Niri, Waybar, wallpaper, Steam, - Bottles, FlClash или desktop behavior: - 1. `fedora/README.md` - 2. нужный целевой конфиг, обычно один из: - - `fedora/niri/config.kdl` - - `fedora/waybar/config.jsonc` - - `fedora/waybar/style.css` - - `fedora/fuzzel/fuzzel.ini` - - `fedora/xsettingsd/xsettingsd.conf` - -- Если задача про старую Bazzite-конфигурацию или миграцию между Bazzite и - Fedora: - 1. `bazzite/README.md` - 2. затем сравнивай с соответствующим файлом в `fedora/` - -- Если задача про кастомные Waybar-модули: - 1. `fedora/khal-calendar/README.md` или `bazzite/khal-calendar/README.md` - 2. `fedora/khal-calendar/Cargo.toml` или `bazzite/khal-calendar/Cargo.toml` - 3. `fedora/mail-counter/README.md` или `bazzite/mail-counter/README.md` - 4. `fedora/mail-counter/Cargo.toml` или `bazzite/mail-counter/Cargo.toml` - -## Repo-specific правила - -- По умолчанию считай `fedora/` текущим и основным направлением. -- Не переноси автоматически старые предположения из `bazzite/` в `fedora/`. -- Если пользователь говорит просто "на федоре", "в desktop-конфиге" или - "в niri", сначала смотри `fedora/`. -- Если пользователь просит исторический контекст, сравнение или миграцию, - используй `bazzite/` как reference, но не как source of truth для новых - изменений. -- Не считай `CLAUDE.md` полной документацией по всему репозиторию: он уже, чем - реальная структура проекта. - -## Как работать безопасно - -- Для desktop-задач не ограничивайся общими рассуждениями: сначала читай - subtree README, потом точечный конфиг. -- Не дублируй содержимое `fedora/README.md` и `bazzite/README.md` в новых - документах без необходимости; эти файлы уже являются каноническими описаниями - профилей. -- Если в рабочем дереве есть несвязанные изменения, не откатывай их и не - расширяй задачу за пределы нужного subtree без явного запроса. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 1f07881..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,38 +0,0 @@ -# Dotfiles - -Personal dotfiles repository for development environment configuration. - -## Structure - -- `nvim/` — Neovim configuration (symlinked to `~/.config/nvim`) - -## Neovim - -Config built for Neovim 0.11+ using native APIs (`vim.lsp.config`, `vim.lsp.enable`, built-in treesitter). - -**Plugin manager:** lazy.nvim (auto-bootstraps on first launch). - -**Languages:** Rust, Zig, TypeScript/JavaScript, C/C++. - -**LSP servers:** -- `rust-analyzer` — via rustaceanvim (install with `rustup component add rust-analyzer`) -- `clangd` — via mason (auto-installed) -- `ts_ls` — via mason (auto-installed) -- `zls` — manual install (`brew install zls`) - -**Key plugins:** telescope, treesitter, nvim-cmp, bufferline, neo-tree, gitsigns, lazygit, lualine, which-key, persistence, alabaster theme. - -**Leader key:** Space. - -## Setup - -```bash -# Symlink nvim config -ln -s ~/Docs/Projects/dotfiles/nvim ~/.config/nvim - -# Install lazygit -brew install lazygit - -# First nvim launch will auto-install plugins, then run: -# :TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash -``` diff --git a/README.md b/README.md index 833ea93..29b3055 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,129 @@ # Dotfiles -Personal dotfiles for development environment configuration. +Личный репозиторий конфигураций Neovim и Linux desktop-сессии на Fedora. -## Structure +## Структура +Сейчас в репозитории поддерживаются два рабочих слоя: + +- `nvim/` — конфигурация Neovim 0.11+; +- `fedora/` — основной профиль Fedora с Niri и QuickShell. + +Новые полноценные системные профили добавляются отдельными каталогами верхнего +уровня: `arch/`, `debian/`, `laptop/` и т. п. Файлы текущего профиля не нужно +смешивать между системами. + +Основные части профиля Fedora: + +| Путь | Назначение | +| --- | --- | +| `fedora/niri/config.kdl` | Композитор, автозапуск, правила окон и хоткеи. | +| `fedora/quickshell/control-center/` | Bar, control center, media popup, OSD и notifications. | +| `fedora/quickshell/scripts/` | Скрипты погоды и NVIDIA GPU для QuickShell. | +| `fedora/systemd/user/` | User unit для QuickShell. | +| `fedora/khal-calendar/` | Rust-модуль календаря. | +| `fedora/mail-counter/` | Rust-счётчик непрочитанных писем Thunderbird. | +| `fedora/wallpapers/wallpaper.png` | Канонический wallpaper профиля. | +| `fedora/packages.txt` | Список пакетов Fedora. | +| `install.sh` | Переносимая установка ссылок и Rust-бинарников. | + +Скрытые каталоги вроде `.git`, `.claude` и `.serena` относятся к инструментам +разработки, а не к desktop-профилю. + +## Установка Fedora + +Установить зависимости из [fedora/packages.txt](fedora/packages.txt): + +```bash +sudo dnf install -y $(grep -vE '^[[:space:]]*(#|$)' fedora/packages.txt) ``` -nvim/ # Neovim config (symlink to ~/.config/nvim) -├── init.lua -└── lua/ - ├── config/ - │ ├── autocmds.lua - │ ├── keymaps.lua - │ └── options.lua - └── plugins/ - ├── bufferline.lua - ├── cmp.lua - ├── colorscheme.lua - ├── editor.lua - ├── git.lua - ├── lsp.lua - ├── lualine.lua - ├── session.lua - ├── telescope.lua - └── treesitter.lua -bazzite/ # Bazzite (Fedora) + Niri compositor configs -├── niri/config.kdl -├── btop/btop.conf -├── glow/glow.yml -├── gtk-3.0/ -│ ├── colors.css -│ ├── gtk.css -│ └── settings.ini -├── gtk-4.0/ -│ ├── colors.css -│ ├── gtk.css -│ └── settings.ini -├── fuzzel/fuzzel.ini -├── waybar/ -│ ├── config.jsonc -│ └── style.css -├── xsettingsd/xsettingsd.conf -├── environment.d/intel-gtk-fix.conf -└── autostart/steam.desktop +Для GPU нужен настроенный NVIDIA-драйвер с рабочим `nvidia-smi`. Затем запустить +установщик из любой директории: + +```bash +./install.sh ``` +Скрипт определяет свой корень автоматически, подключает конфигурации Fedora и +Neovim через ссылки в `$HOME/.config`, создаёт +`$HOME/.local/bin`, подключает QuickShell и systemd unit, создаёт ссылку +`$HOME/.config/wallpaper.png`, собирает оба Rust-модуля и устанавливает их в +`$HOME/.local/bin`. + +Обычные файлы конфигурации не должны молча затираться установщиком: если на +месте ссылки уже лежит реальный файл или каталог, скрипт остановится и сообщит +об этом. + +## QuickShell + +Niri запускает `quickshell-control-center.service`, а unit запускает shell из +стабильной ссылки `$HOME/.config/quickshell/control-center`. После изменения +QML применить конфигурацию можно так: + +```bash +systemctl --user daemon-reload +systemctl --user restart quickshell-control-center.service +``` + +Ручной запуск и IPC: + +```bash +qs -p "$HOME/.config/quickshell/control-center" +qs ipc -p "$HOME/.config/quickshell/control-center" call controlcenter toggle +qs ipc -p "$HOME/.config/quickshell/control-center" call controlcenter close +qs ipc -p "$HOME/.config/quickshell/control-center" call osd volume_up +``` + +Bar показывает погоду, загрузку GPU, CPU, память, root filesystem, раскладку, +аудиовход, календарь и остальные интерактивные индикаторы. Температурные пороги +настраиваются в control center; отдельная старая панель больше не используется. + +## Rust-модули + +Установщик выполняет сборку автоматически. Для ручной пересборки: + +```bash +mkdir -p "$HOME/.local/bin" +cargo build --release --manifest-path fedora/khal-calendar/Cargo.toml +install -m 755 fedora/khal-calendar/target/release/khal-calendar "$HOME/.local/bin/khal-calendar" +cargo build --release --manifest-path fedora/mail-counter/Cargo.toml +install -m 755 fedora/mail-counter/target/release/mail-counter "$HOME/.local/bin/mail-counter" +``` + +Календарь использует `khal`, а mail-counter читает Thunderbird +`global-messages-db.sqlite` и отдаёт JSON, который читает QuickShell. + ## Neovim -Requires Neovim 0.11+ — uses native APIs (`vim.lsp.config`, `vim.lsp.enable`, built-in treesitter). +Конфигурация использует lazy.nvim, native LSP API и встроенный Treesitter. +Leader — Space. Поддерживаемые языки: Rust, Zig, TypeScript/JavaScript и C/C++. -**Plugin manager:** lazy.nvim (auto-bootstraps on first launch). +LSP-серверы: -**Leader key:** Space. +- `rust-analyzer` через rustaceanvim; +- `clangd` и `ts_ls` через Mason; +- `zls` устанавливается отдельно в системе. -### Languages +Первый запуск Neovim установит плагины. Затем можно установить парсеры: -Rust, Zig, TypeScript/JavaScript, C/C++. - -### LSP servers - -| Server | Language | Install | -|---|---|---| -| rust-analyzer | Rust | `rustup component add rust-analyzer` (via rustaceanvim) | -| clangd | C/C++ | auto-installed via mason | -| ts_ls | TypeScript/JS | auto-installed via mason | -| zls | Zig | `brew install zls` | - -### Key plugins - -telescope, treesitter, nvim-cmp, bufferline, neo-tree, gitsigns, lazygit, lualine, which-key, persistence, alabaster theme. - -## Bazzite - -Configs for Bazzite (Fedora Atomic) with Niri Wayland compositor. - -| Config | Description | -|---|---| -| `niri/config.kdl` | Niri compositor | -| `fuzzel/fuzzel.ini` | App launcher | -| `waybar/` | Top panel (config + style) | -| `btop/btop.conf` | System monitor | -| `glow/glow.yml` | Terminal markdown viewer | -| `gtk-3.0/`, `gtk-4.0/` | GTK theme and colors | -| `xsettingsd/xsettingsd.conf` | X11/XWayland settings (fonts, theme) | -| `environment.d/intel-gtk-fix.conf` | Intel GPU environment fix | -| `autostart/steam.desktop` | Steam autostart | - -## Setup - -### macOS (Neovim) - -```bash -ln -s ~/Docs/Projects/dotfiles/nvim ~/.config/nvim -brew install lazygit - -# First nvim launch will auto-install plugins, then run: -# :TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash +```vim +:TSInstall rust zig typescript javascript tsx c cpp lua json yaml toml html css markdown bash ``` -### Bazzite +Если нужно подключить только Neovim вручную: ```bash -# Symlink configs to ~/.config/ -for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do - ln -sf ~/Docs/Projects/dotfiles/bazzite/$dir ~/.config/$dir -done +ln -sfn "$PWD/nvim" "${XDG_CONFIG_HOME:-$HOME/.config}/nvim" ``` + +## Правила работы с репозиторием + +- Сначала читать этот `README.md`, затем целевой конфиг. +- `fedora/` — текущий source of truth для Fedora, Niri и QuickShell. +- Незакоммиченные правки пользователя сохранять; несвязанные файлы не откатывать. +- Проверять runtime-конфигурацию, если поведение системы расходится с текстом + checkout. +- Не добавлять секреты, токены, кэши, логи и машинный мусор. +- Markdown-документация живёт только в корневом `README.md`; новые инструкции + добавлять туда, а не создавать отдельные README. diff --git a/bazzite/.DS_Store b/bazzite/.DS_Store deleted file mode 100644 index 39ff9b8..0000000 Binary files a/bazzite/.DS_Store and /dev/null differ diff --git a/bazzite/README.md b/bazzite/README.md deleted file mode 100644 index 36739a7..0000000 --- a/bazzite/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Конфиги рабочего стола Bazzite - -Эта папка содержит конфигурацию рабочего стола Bazzite для Wayland-сессии на -Niri. Идея в том, чтобы подключать эти файлы в `~/.config` на Bazzite-машине и -держать живую конфигурацию рабочего стола синхронизированной с этим -репозиторием. - -## Что здесь настроено - -| Путь | Назначение | -|---|---| -| `niri/config.kdl` | Конфиг Niri: ввод, монитор, раскладка окон, автозапуск, правила окон, хоткеи. | -| `waybar/` | Верхняя панель: конфиг, CSS в стиле Catppuccin и custom-модули. | -| `waybar/scripts/gpu.sh` | Модуль Waybar для загрузки и температуры NVIDIA GPU через `nvidia-smi`. | -| `waybar/scripts/weather.sh` | Модуль Waybar с погодой через `wttr.in`. | -| `khal-calendar/` | Rust-версия календарного модуля Waybar. | -| `mail-counter/` | Rust-модуль Waybar для счетчика непрочитанных писем Thunderbird. | -| `fuzzel/fuzzel.ini` | Тема лаунчера Fuzzel на цветах Catppuccin Latte. | -| `btop/btop.conf` | Настройки системного монитора btop. | -| `glow/glow.yml` | Настройки терминального Markdown-viewer Glow. | -| `gtk-3.0/`, `gtk-4.0/` | GTK-настройки и цветовые файлы Breeze/Catppuccin. | -| `xsettingsd/xsettingsd.conf` | Настройки GTK, курсора, иконок, шрифта и DPI для X11/XWayland-приложений. | -| `environment.d/intel-gtk-fix.conf` | Переменная окружения сессии: `GSK_RENDERER=gl`. | -| `autostart/steam.desktop` | Автозапуск Steam через Bazzite Steam wrapper. | -| `wallpapers/image.png` | Текущая картинка рабочего стола для `swaybg`. | - -## Как это работает - -Niri запускает `swaybg` и `waybar` из `niri/config.kdl`. `swaybg` рисует -wallpaper, Waybar поднимает: - -- встроенные Niri-модули для рабочих столов, заголовка окна и раскладки - клавиатуры; -- системные модули для звука, сети, CPU, памяти, температуры, диска, privacy, - power profile и tray; -- custom-модули для почты Thunderbird, погоды, NVIDIA GPU и календаря из - `khal`. - -Календарный модуль печатает JSON для Waybar и показывает Pango-tooltip с текущим -месяцем, подсвеченными днями с событиями и ближайшими событиями из `khal`. -Активная реализация сейчас - скомпилированный Rust-бинарник: - -```jsonc -"exec": "~/.config/waybar/scripts/khal-calendar" -``` - -## Ожидаемые программы - -Для полной работы конфигурации на Bazzite ожидаются: - -- `niri` -- `waybar` -- `fuzzel` -- `btop` -- `glow` -- `xsettingsd` -- `alacritty` -- `swaybg` -- `khal`, `ikhal`, `vdirsyncer` -- `nvidia-smi` -- `curl` -- `cargo` для пересборки `khal-calendar` и `mail-counter` - -## Установка - -Подключить директории в `~/.config`: - -```bash -for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do - ln -sfn ~/dotfiles/bazzite/$dir ~/.config/$dir -done -mkdir -p ~/Pictures/Wallpapers -ln -sfn ~/dotfiles/bazzite/wallpapers/image.png ~/Pictures/Wallpapers/image.png -``` - -Если репозиторий лежит не в `~/dotfiles`, путь нужно поправить. - -## Сборка календарного модуля - -Собрать и установить Rust-бинарник календаря на Bazzite: - -```bash -cd ~/dotfiles/bazzite/khal-calendar -cargo build --release -install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar -``` - -Исходники остаются в `khal-calendar/`; установленный бинарник лежит в -`~/.config/waybar/scripts/`. - -## Сборка почтового модуля - -Собрать и установить Rust-бинарник счетчика писем на Bazzite: - -```bash -cd ~/dotfiles/bazzite/mail-counter -cargo build --release -install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail -``` - -Модуль читает `global-messages-db.sqlite` из профиля Thunderbird и печатает JSON -для `custom/mail` в Waybar. - -## Перезагрузка - -После изменения конфига или CSS Waybar: - -```bash -pkill -SIGUSR2 waybar -``` - -Если Waybar не подхватил изменения, нужно перезапустить Waybar вручную или -перезапустить Niri-сессию. diff --git a/bazzite/autostart/steam.desktop b/bazzite/autostart/steam.desktop deleted file mode 100644 index 178d937..0000000 --- a/bazzite/autostart/steam.desktop +++ /dev/null @@ -1,281 +0,0 @@ -[Desktop Entry] -Name=Steam -Comment=Application for managing and playing games on Steam -Comment[pt_BR]=Aplicativo para jogar e gerenciar jogos no Steam -Comment[bg]=Приложение за ръководене и пускане на игри в Steam -Comment[cs]=Aplikace pro spravování a hraní her ve službě Steam -Comment[da]=Applikation til at håndtere og spille spil på Steam -Comment[nl]=Applicatie voor het beheer en het spelen van games op Steam -Comment[fi]=Steamin pelien hallintaan ja pelaamiseen tarkoitettu sovellus -Comment[fr]=Application de gestion et d'utilisation des jeux sur Steam -Comment[de]=Anwendung zum Verwalten und Spielen von Spielen auf Steam -Comment[el]=Εφαρμογή διαχείρισης παιχνιδιών στο Steam -Comment[hu]=Alkalmazás a Steames játékok futtatásához és kezeléséhez -Comment[it]=Applicazione per la gestione e l'esecuzione di giochi su Steam -Comment[ja]=Steam 上でゲームを管理&プレイするためのアプリケーション -Comment[ko]=Steam에 있는 게임을 관리하고 플레이할 수 있는 응용 프로그램 -Comment[no]=Program for å administrere og spille spill på Steam -Comment[pt_PT]=Aplicação para organizar e executar jogos no Steam -Comment[pl]=Aplikacja do zarządzania i uruchamiania gier na platformie Steam -Comment[ro]=Aplicație pentru administrarea și jucatul jocurilor pe Steam -Comment[ru]=Приложение для игр и управления играми в Steam -Comment[es]=Aplicación para administrar y ejecutar juegos en Steam -Comment[sv]=Ett program för att hantera samt spela spel på Steam -Comment[zh_CN]=管理和进行 Steam 游戏的应用程序 -Comment[zh_TW]=管理並執行 Steam 遊戲的應用程式 -Comment[th]=โปรแกรมสำหรับจัดการและเล่นเกมบน Steam -Comment[tr]=Steam üzerinden oyun oynama ve düzenleme uygulaması -Comment[uk]=Програма для керування іграми та запуску ігор у Steam -Comment[vi]=Ứng dụng để quản lý và chơi trò chơi trên Steam -Exec=/usr/bin/bazzite-steam -silent %U -Icon=steam -Terminal=false -Type=Application -Categories=Network;FileTransfer;Game; -MimeType=x-scheme-handler/steam;x-scheme-handler/steamlink; -Actions=Store;Community;Library;Servers;Screenshots;News;Settings;BigPicture;Friends; -X-Desktop-File-Install-Version=0.28 - -[Desktop Action Store] -Name=Store -Name[pt_BR]=Loja -Name[bg]=Магазин -Name[cs]=Obchod -Name[da]=Butik -Name[nl]=Winkel -Name[fi]=Kauppa -Name[fr]=Magasin -Name[de]=Shop -Name[el]=ΚΑΤΑΣΤΗΜΑ -Name[hu]=Áruház -Name[it]=Negozio -Name[ja]=ストア -Name[ko]=상점 -Name[no]=Butikk -Name[pt_PT]=Loja -Name[pl]=Sklep -Name[ro]=Magazin -Name[ru]=Магазин -Name[es]=Tienda -Name[sv]=Butik -Name[zh_CN]=商店 -Name[zh_TW]=商店 -Name[th]=ร้านค้า -Name[tr]=Mağaza -Name[uk]=Крамниця -Name[vi]=Cửa hàng -Exec=/usr/bin/bazzite-steam steam://store - -[Desktop Action Community] -Name=Community -Name[pt_BR]=Comunidade -Name[bg]=Общност -Name[cs]=Komunita -Name[da]=Fællesskab -Name[nl]=Community -Name[fi]=Yhteisö -Name[fr]=Communauté -Name[de]=Community -Name[el]=Κοινότητα -Name[hu]=Közösség -Name[it]=Comunità -Name[ja]=コミュニティ -Name[ko]=커뮤니티 -Name[no]=Samfunn -Name[pt_PT]=Comunidade -Name[pl]=Społeczność -Name[ro]=Comunitate -Name[ru]=Сообщество -Name[es]=Comunidad -Name[sv]=Gemenskap -Name[zh_CN]=社区 -Name[zh_TW]=社群 -Name[th]=ชุมชน -Name[tr]=Topluluk -Name[uk]=Спільнота -Name[vi]=Cộng đồng -Exec=/usr/bin/bazzite-steam steam://url/CommunityHome/ - -[Desktop Action Library] -Name=Library -Name[pt_BR]=Biblioteca -Name[bg]=Библиотека -Name[cs]=Knihovna -Name[da]=Bibliotek -Name[nl]=Bibliotheek -Name[fi]=Kokoelma -Name[fr]=Bibliothèque -Name[de]=Bibliothek -Name[el]=Συλλογή -Name[hu]=Könyvtár -Name[it]=Libreria -Name[ja]=ライブラリ -Name[ko]=라이브러리 -Name[no]=Bibliotek -Name[pt_PT]=Biblioteca -Name[pl]=Biblioteka -Name[ro]=Colecţie -Name[ru]=Библиотека -Name[es]=Biblioteca -Name[sv]=Bibliotek -Name[zh_CN]=库 -Name[zh_TW]=收藏庫 -Name[th]=คลัง -Name[tr]=Kütüphane -Name[uk]=Бібліотека -Name[vi]=Thư viện -Exec=/usr/bin/bazzite-steam steam://open/games - -[Desktop Action Servers] -Name=Servers -Name[pt_BR]=Servidores -Name[bg]=Сървъри -Name[cs]=Servery -Name[da]=Servere -Name[nl]=Servers -Name[fi]=Palvelimet -Name[fr]=Serveurs -Name[de]=Server -Name[el]=Διακομιστές -Name[hu]=Szerverek -Name[it]=Server -Name[ja]=サーバー -Name[ko]=서버 -Name[no]=Tjenere -Name[pt_PT]=Servidores -Name[pl]=Serwery -Name[ro]=Servere -Name[ru]=Серверы -Name[es]=Servidores -Name[sv]=Servrar -Name[zh_CN]=服务器 -Name[zh_TW]=伺服器 -Name[th]=เซิร์ฟเวอร์ -Name[tr]=Sunucular -Name[uk]=Сервери -Name[vi]=Máy chủ -Exec=/usr/bin/bazzite-steam steam://open/servers - -[Desktop Action Screenshots] -Name=Screenshots -Name[pt_BR]=Capturas de tela -Name[bg]=Снимки -Name[cs]=Snímky obrazovky -Name[da]=Skærmbilleder -Name[nl]=Screenshots -Name[fi]=Kuvankaappaukset -Name[fr]=Captures d'écran -Name[de]=Screenshots -Name[el]=Φωτογραφίες -Name[hu]=Képernyőmentések -Name[it]=Screenshot -Name[ja]=スクリーンショット -Name[ko]=스크린샷 -Name[no]=Skjermbilder -Name[pt_PT]=Capturas de ecrã -Name[pl]=Zrzuty ekranu -Name[ro]=Capturi de ecran -Name[ru]=Скриншоты -Name[es]=Capturas -Name[sv]=Skärmdumpar -Name[zh_CN]=截图 -Name[zh_TW]=螢幕擷圖 -Name[th]=ภาพหน้าจอ -Name[tr]=Ekran Görüntüleri -Name[uk]=Скріншоти -Name[vi]=Ảnh chụp -Exec=/usr/bin/bazzite-steam steam://open/screenshots - -[Desktop Action News] -Name=News -Name[pt_BR]=Notícias -Name[bg]=Новини -Name[cs]=Zprávy -Name[da]=Nyheder -Name[nl]=Nieuws -Name[fi]=Uutiset -Name[fr]=Actualités -Name[de]=Neuigkeiten -Name[el]=Νέα -Name[hu]=Hírek -Name[it]=Notizie -Name[ja]=ニュース -Name[ko]=뉴스 -Name[no]=Nyheter -Name[pt_PT]=Novidades -Name[pl]=Aktualności -Name[ro]=Știri -Name[ru]=Новости -Name[es]=Noticias -Name[sv]=Nyheter -Name[zh_CN]=新闻 -Name[zh_TW]=新聞 -Name[th]=ข่าวสาร -Name[tr]=Haberler -Name[uk]=Новини -Name[vi]=Tin tức -Exec=/usr/bin/bazzite-steam steam://openurl/https://store.steampowered.com/news - -[Desktop Action Settings] -Name=Settings -Name[pt_BR]=Configurações -Name[bg]=Настройки -Name[cs]=Nastavení -Name[da]=Indstillinger -Name[nl]=Instellingen -Name[fi]=Asetukset -Name[fr]=Paramètres -Name[de]=Einstellungen -Name[el]=Ρυθμίσεις -Name[hu]=Beállítások -Name[it]=Impostazioni -Name[ja]=設定 -Name[ko]=설정 -Name[no]=Innstillinger -Name[pt_PT]=Definições -Name[pl]=Ustawienia -Name[ro]=Setări -Name[ru]=Настройки -Name[es]=Parámetros -Name[sv]=Inställningar -Name[zh_CN]=设置 -Name[zh_TW]=設定 -Name[th]=การตั้งค่า -Name[tr]=Ayarlar -Name[uk]=Налаштування -Name[vi]=Thiết lập -Exec=/usr/bin/bazzite-steam steam://open/settings - -[Desktop Action BigPicture] -Name=Big Picture -Exec=/usr/bin/bazzite-steam steam://open/bigpicture - -[Desktop Action Friends] -Name=Friends -Name[pt_BR]=Amigos -Name[bg]=Приятели -Name[cs]=Přátelé -Name[da]=Venner -Name[nl]=Vrienden -Name[fi]=Kaverit -Name[fr]=Amis -Name[de]=Freunde -Name[el]=Φίλοι -Name[hu]=Barátok -Name[it]=Amici -Name[ja]=フレンド -Name[ko]=친구 -Name[no]=Venner -Name[pt_PT]=Amigos -Name[pl]=Znajomi -Name[ro]=Prieteni -Name[ru]=Друзья -Name[es]=Amigos -Name[sv]=Vänner -Name[zh_CN]=好友 -Name[zh_TW]=好友 -Name[th]=เพื่อน -Name[tr]=Arkadaşlar -Name[uk]=Друзі -Name[vi]=Bạn bè -Exec=/usr/bin/bazzite-steam steam://open/friends diff --git a/bazzite/btop/btop.conf b/bazzite/btop/btop.conf deleted file mode 100644 index b1f33d0..0000000 --- a/bazzite/btop/btop.conf +++ /dev/null @@ -1,257 +0,0 @@ -#? Config file for btop v. 1.4.5 - -#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. -#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" -color_theme = "Default" - -#* If the theme set background should be shown, set to False if you want terminal background transparency. -theme_background = True - -#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false. -truecolor = True - -#* Set to true to force tty mode regardless if a real tty has been detected or not. -#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols. -force_tty = False - -#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets. -#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box. -#* Use whitespace " " as separator between different presets. -#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty" -presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty" - -#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists. -#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift. -vim_keys = False - -#* Rounded corners on boxes, is ignored if TTY mode is ON. -rounded_corners = True - -#* Default symbols to use for graph creation, "braille", "block" or "tty". -#* "braille" offers the highest resolution but might not be included in all fonts. -#* "block" has half the resolution of braille but uses more common characters. -#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY. -#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view. -graph_symbol = "braille" - -# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". -graph_symbol_cpu = "default" - -# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty". -graph_symbol_gpu = "default" - -# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". -graph_symbol_mem = "default" - -# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". -graph_symbol_net = "default" - -# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". -graph_symbol_proc = "default" - -#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace. -shown_boxes = "proc cpu mem net" - -#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs. -update_ms = 1000 - -#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct", -#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly. -proc_sorting = "memory" - -#* Reverse sorting order, True or False. -proc_reversed = False - -#* Show processes as a tree. -proc_tree = False - -#* Use the cpu graph colors in the process list. -proc_colors = True - -#* Use a darkening gradient in the process list. -proc_gradient = True - -#* If process cpu usage should be of the core it's running on or usage of the total available cpu power. -proc_per_core = False - -#* Show process memory as bytes instead of percent. -proc_mem_bytes = True - -#* Show cpu graph for each process. -proc_cpu_graphs = True - -#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate) -proc_info_smaps = False - -#* Show proc box on left side of screen instead of right. -proc_left = False - -#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop). -proc_filter_kernel = False - -#* In tree-view, always accumulate child process resources in the parent process. -proc_aggregate = False - -#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available. -#* Select from a list of detected attributes from the options menu. -cpu_graph_upper = "Auto" - -#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available. -#* Select from a list of detected attributes from the options menu. -cpu_graph_lower = "Auto" - -#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off". -show_gpu_info = "Auto" - -#* Toggles if the lower CPU graph should be inverted. -cpu_invert_lower = True - -#* Set to True to completely disable the lower CPU graph. -cpu_single_graph = False - -#* Show cpu box at bottom of screen instead of top. -cpu_bottom = False - -#* Shows the system uptime in the CPU box. -show_uptime = True - -#* Shows the CPU package current power consumption in watts. Requires running `make setcap` or `make setuid` or running with sudo. -show_cpu_watts = True - -#* Show cpu temperature. -check_temp = True - -#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors. -cpu_sensor = "Auto" - -#* Show temperatures for cpu cores also if check_temp is True and sensors has been found. -show_coretemp = True - -#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core. -#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine. -#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries. -#* Example: "4:0 5:1 6:3" -cpu_core_map = "" - -#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine". -temp_scale = "celsius" - -#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024. -base_10_sizes = False - -#* Show CPU frequency. -show_cpu_freq = True - -#* Draw a clock at top of screen, formatting according to strftime, empty string to disable. -#* Special formatting: /host = hostname | /user = username | /uptime = system uptime -clock_format = "%X" - -#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort. -background_update = True - -#* Custom cpu model name, empty string to disable. -custom_cpu_name = "" - -#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ". -#* Only disks matching the filter will be shown. Prepend exclude= to only show disks not matching the filter. Examples: disk_filter="/boot /home/user", disks_filter="exclude=/boot /home/user" -disks_filter = "" - -#* Show graphs instead of meters for memory values. -mem_graphs = True - -#* Show mem box below net box instead of above. -mem_below_net = False - -#* Count ZFS ARC in cached and available memory. -zfs_arc_cached = True - -#* If swap memory should be shown in memory box. -show_swap = True - -#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk. -swap_disk = True - -#* If mem box should be split to also show disks info. -show_disks = True - -#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar. -only_physical = True - -#* Read disks list from /etc/fstab. This also disables only_physical. -use_fstab = True - -#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool) -zfs_hide_datasets = False - -#* Set to true to show available disk space for privileged users. -disk_free_priv = False - -#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view. -show_io_stat = True - -#* Toggles io mode for disks, showing big graphs for disk read/write speeds. -io_mode = False - -#* Set to True to show combined read/write io graphs in io mode. -io_graph_combined = False - -#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ". -#* Example: "/mnt/media:100 /:20 /boot:1". -io_graph_speeds = "" - -#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False. -net_download = 100 - -net_upload = 100 - -#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest. -net_auto = True - -#* Sync the auto scaling for download and upload to whichever currently has the highest scale. -net_sync = True - -#* Starts with the Network Interface specified here. -net_iface = "" - -#* "True" shows bitrates in base 10 (Kbps, Mbps). "False" shows bitrates in binary sizes (Kibps, Mibps, etc.). "Auto" uses base_10_sizes. -base_10_bitrate = "Auto" - -#* Show battery stats in top right if battery is present. -show_battery = True - -#* Which battery to use if multiple are present. "Auto" for auto detection. -selected_battery = "Auto" - -#* Show power stats of battery next to charge indicator. -show_battery_watts = True - -#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG". -#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info. -log_level = "WARNING" - -#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards. -nvml_measure_pcie_speeds = True - -#* Measure PCIe throughput on AMD cards, may impact performance on certain cards. -rsmi_measure_pcie_speeds = True - -#* Horizontally mirror the GPU graph. -gpu_mirror_graph = True - -#* Custom gpu0 model name, empty string to disable. -custom_gpu_name0 = "" - -#* Custom gpu1 model name, empty string to disable. -custom_gpu_name1 = "" - -#* Custom gpu2 model name, empty string to disable. -custom_gpu_name2 = "" - -#* Custom gpu3 model name, empty string to disable. -custom_gpu_name3 = "" - -#* Custom gpu4 model name, empty string to disable. -custom_gpu_name4 = "" - -#* Custom gpu5 model name, empty string to disable. -custom_gpu_name5 = "" diff --git a/bazzite/environment.d/intel-gtk-fix.conf b/bazzite/environment.d/intel-gtk-fix.conf deleted file mode 100644 index 75fe23c..0000000 --- a/bazzite/environment.d/intel-gtk-fix.conf +++ /dev/null @@ -1 +0,0 @@ -GSK_RENDERER=gl diff --git a/bazzite/fuzzel/fuzzel.ini b/bazzite/fuzzel/fuzzel.ini deleted file mode 100644 index b784c59..0000000 --- a/bazzite/fuzzel/fuzzel.ini +++ /dev/null @@ -1,18 +0,0 @@ -# Catppuccin Latte (Blue) + 70% opacity background - -[colors] -background=eff1f5b3 -text=4c4f69ff -prompt=5c5f77ff -placeholder=8c8fa1ff -input=4c4f69ff -match=1e66f5ff -selection=acb0beff -selection-text=4c4f69ff -selection-match=1e66f5ff -counter=8c8fa1ff -border=f38ba8ff - -[border] -width=2 -radius=6 diff --git a/bazzite/glow/glow.yml b/bazzite/glow/glow.yml deleted file mode 100644 index 749e1ec..0000000 --- a/bazzite/glow/glow.yml +++ /dev/null @@ -1,10 +0,0 @@ -# style name or JSON path (default "auto") -style: "auto" -# mouse support (TUI-mode only) -mouse: false -# use pager to display markdown -pager: false -# word-wrap at width -width: 80 -# show all files, including hidden and ignored. -all: false diff --git a/bazzite/gtk-3.0/colors.css b/bazzite/gtk-3.0/colors.css deleted file mode 100644 index 0c919b2..0000000 --- a/bazzite/gtk-3.0/colors.css +++ /dev/null @@ -1,84 +0,0 @@ -@define-color borders_breeze #bcbebf; -@define-color content_view_bg_breeze #ffffff; -@define-color error_color_backdrop_breeze #da4453; -@define-color error_color_breeze #da4453; -@define-color error_color_insensitive_backdrop_breeze #f0b1b8; -@define-color error_color_insensitive_breeze #f0b1b8; -@define-color insensitive_base_color_breeze #f3f3f3; -@define-color insensitive_base_fg_color_breeze #aaabac; -@define-color insensitive_bg_color_breeze #e3e5e7; -@define-color insensitive_borders_breeze #d2d4d6; -@define-color insensitive_fg_color_breeze #a0a1a3; -@define-color insensitive_selected_bg_color_breeze #e3e5e7; -@define-color insensitive_selected_fg_color_breeze #a0a1a3; -@define-color insensitive_unfocused_bg_color_breeze #e3e5e7; -@define-color insensitive_unfocused_fg_color_breeze #a0a1a3; -@define-color insensitive_unfocused_selected_bg_color_breeze #e3e5e7; -@define-color insensitive_unfocused_selected_fg_color_breeze #a0a1a3; -@define-color link_color_breeze #2980b9; -@define-color link_visited_color_breeze #9b59b6; -@define-color success_color_backdrop_breeze #27ae60; -@define-color success_color_breeze #27ae60; -@define-color success_color_insensitive_backdrop_breeze #abd8be; -@define-color success_color_insensitive_breeze #abd8be; -@define-color theme_base_color_breeze #ffffff; -@define-color theme_bg_color_breeze #eff0f1; -@define-color theme_button_background_backdrop_breeze #fcfcfc; -@define-color theme_button_background_backdrop_insensitive_breeze #f0f0f0; -@define-color theme_button_background_insensitive_breeze #f0f0f0; -@define-color theme_button_background_normal_breeze #fcfcfc; -@define-color theme_button_decoration_focus_backdrop_breeze #3daee9; -@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_focus_breeze #3daee9; -@define-color theme_button_decoration_focus_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_hover_backdrop_breeze #3daee9; -@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_hover_breeze #3daee9; -@define-color theme_button_decoration_hover_insensitive_breeze #a2d8f3; -@define-color theme_button_foreground_active_backdrop_breeze #232629; -@define-color theme_button_foreground_active_backdrop_insensitive_breeze #a0a1a3; -@define-color theme_button_foreground_active_breeze #ffffff; -@define-color theme_button_foreground_active_insensitive_breeze #a0a1a3; -@define-color theme_button_foreground_backdrop_breeze #232629; -@define-color theme_button_foreground_backdrop_insensitive_breeze #a8a9aa; -@define-color theme_button_foreground_insensitive_breeze #a8a9aa; -@define-color theme_button_foreground_normal_breeze #232629; -@define-color theme_fg_color_breeze #232629; -@define-color theme_header_background_backdrop_breeze #eff0f1; -@define-color theme_header_background_breeze #dee0e2; -@define-color theme_header_background_light_breeze #eff0f1; -@define-color theme_header_foreground_backdrop_breeze #232629; -@define-color theme_header_foreground_breeze #232629; -@define-color theme_header_foreground_insensitive_backdrop_breeze #232629; -@define-color theme_header_foreground_insensitive_breeze #232629; -@define-color theme_hovering_selected_bg_color_breeze #3daee9; -@define-color theme_selected_bg_color_breeze #3daee9; -@define-color theme_selected_fg_color_breeze #ffffff; -@define-color theme_text_color_breeze #232629; -@define-color theme_titlebar_background_backdrop_breeze #eff0f1; -@define-color theme_titlebar_background_breeze #dee0e2; -@define-color theme_titlebar_background_light_breeze #eff0f1; -@define-color theme_titlebar_foreground_backdrop_breeze #232629; -@define-color theme_titlebar_foreground_breeze #232629; -@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #232629; -@define-color theme_titlebar_foreground_insensitive_breeze #232629; -@define-color theme_unfocused_base_color_breeze #ffffff; -@define-color theme_unfocused_bg_color_breeze #eff0f1; -@define-color theme_unfocused_fg_color_breeze #232629; -@define-color theme_unfocused_selected_bg_color_alt_breeze #c2e0f5; -@define-color theme_unfocused_selected_bg_color_breeze #c2e0f5; -@define-color theme_unfocused_selected_fg_color_breeze #232629; -@define-color theme_unfocused_text_color_breeze #232629; -@define-color theme_unfocused_view_bg_color_breeze #f3f3f3; -@define-color theme_unfocused_view_text_color_breeze #aaabac; -@define-color theme_view_active_decoration_color_breeze #3daee9; -@define-color theme_view_hover_decoration_color_breeze #3daee9; -@define-color tooltip_background_breeze #f7f7f7; -@define-color tooltip_border_breeze #c2c3c4; -@define-color tooltip_text_breeze #232629; -@define-color unfocused_borders_breeze #bcbebf; -@define-color unfocused_insensitive_borders_breeze #d2d4d6; -@define-color warning_color_backdrop_breeze #f67400; -@define-color warning_color_breeze #f67400; -@define-color warning_color_insensitive_backdrop_breeze #fbc289; -@define-color warning_color_insensitive_breeze #fbc289; diff --git a/bazzite/gtk-3.0/gtk.css b/bazzite/gtk-3.0/gtk.css deleted file mode 100644 index c9763f7..0000000 --- a/bazzite/gtk-3.0/gtk.css +++ /dev/null @@ -1 +0,0 @@ -@import 'colors.css'; \ No newline at end of file diff --git a/bazzite/gtk-3.0/settings.ini b/bazzite/gtk-3.0/settings.ini deleted file mode 100644 index 104481d..0000000 --- a/bazzite/gtk-3.0/settings.ini +++ /dev/null @@ -1,17 +0,0 @@ -[Settings] -gtk-application-prefer-dark-theme=false -gtk-button-images=true -gtk-cursor-blink=true -gtk-cursor-blink-time=1000 -gtk-cursor-theme-name=breeze_cursors -gtk-cursor-theme-size=24 -gtk-decoration-layout=icon:minimize,maximize,close -gtk-enable-animations=true -gtk-font-name=Noto Sans, 10 -gtk-icon-theme-name=breeze -gtk-menu-images=true -gtk-modules=colorreload-gtk-module -gtk-primary-button-warps-slider=true -gtk-sound-theme-name=ocean -gtk-toolbar-style=3 -gtk-xft-dpi=98304 diff --git a/bazzite/gtk-4.0/colors.css b/bazzite/gtk-4.0/colors.css deleted file mode 100644 index 0c919b2..0000000 --- a/bazzite/gtk-4.0/colors.css +++ /dev/null @@ -1,84 +0,0 @@ -@define-color borders_breeze #bcbebf; -@define-color content_view_bg_breeze #ffffff; -@define-color error_color_backdrop_breeze #da4453; -@define-color error_color_breeze #da4453; -@define-color error_color_insensitive_backdrop_breeze #f0b1b8; -@define-color error_color_insensitive_breeze #f0b1b8; -@define-color insensitive_base_color_breeze #f3f3f3; -@define-color insensitive_base_fg_color_breeze #aaabac; -@define-color insensitive_bg_color_breeze #e3e5e7; -@define-color insensitive_borders_breeze #d2d4d6; -@define-color insensitive_fg_color_breeze #a0a1a3; -@define-color insensitive_selected_bg_color_breeze #e3e5e7; -@define-color insensitive_selected_fg_color_breeze #a0a1a3; -@define-color insensitive_unfocused_bg_color_breeze #e3e5e7; -@define-color insensitive_unfocused_fg_color_breeze #a0a1a3; -@define-color insensitive_unfocused_selected_bg_color_breeze #e3e5e7; -@define-color insensitive_unfocused_selected_fg_color_breeze #a0a1a3; -@define-color link_color_breeze #2980b9; -@define-color link_visited_color_breeze #9b59b6; -@define-color success_color_backdrop_breeze #27ae60; -@define-color success_color_breeze #27ae60; -@define-color success_color_insensitive_backdrop_breeze #abd8be; -@define-color success_color_insensitive_breeze #abd8be; -@define-color theme_base_color_breeze #ffffff; -@define-color theme_bg_color_breeze #eff0f1; -@define-color theme_button_background_backdrop_breeze #fcfcfc; -@define-color theme_button_background_backdrop_insensitive_breeze #f0f0f0; -@define-color theme_button_background_insensitive_breeze #f0f0f0; -@define-color theme_button_background_normal_breeze #fcfcfc; -@define-color theme_button_decoration_focus_backdrop_breeze #3daee9; -@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_focus_breeze #3daee9; -@define-color theme_button_decoration_focus_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_hover_backdrop_breeze #3daee9; -@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #a2d8f3; -@define-color theme_button_decoration_hover_breeze #3daee9; -@define-color theme_button_decoration_hover_insensitive_breeze #a2d8f3; -@define-color theme_button_foreground_active_backdrop_breeze #232629; -@define-color theme_button_foreground_active_backdrop_insensitive_breeze #a0a1a3; -@define-color theme_button_foreground_active_breeze #ffffff; -@define-color theme_button_foreground_active_insensitive_breeze #a0a1a3; -@define-color theme_button_foreground_backdrop_breeze #232629; -@define-color theme_button_foreground_backdrop_insensitive_breeze #a8a9aa; -@define-color theme_button_foreground_insensitive_breeze #a8a9aa; -@define-color theme_button_foreground_normal_breeze #232629; -@define-color theme_fg_color_breeze #232629; -@define-color theme_header_background_backdrop_breeze #eff0f1; -@define-color theme_header_background_breeze #dee0e2; -@define-color theme_header_background_light_breeze #eff0f1; -@define-color theme_header_foreground_backdrop_breeze #232629; -@define-color theme_header_foreground_breeze #232629; -@define-color theme_header_foreground_insensitive_backdrop_breeze #232629; -@define-color theme_header_foreground_insensitive_breeze #232629; -@define-color theme_hovering_selected_bg_color_breeze #3daee9; -@define-color theme_selected_bg_color_breeze #3daee9; -@define-color theme_selected_fg_color_breeze #ffffff; -@define-color theme_text_color_breeze #232629; -@define-color theme_titlebar_background_backdrop_breeze #eff0f1; -@define-color theme_titlebar_background_breeze #dee0e2; -@define-color theme_titlebar_background_light_breeze #eff0f1; -@define-color theme_titlebar_foreground_backdrop_breeze #232629; -@define-color theme_titlebar_foreground_breeze #232629; -@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #232629; -@define-color theme_titlebar_foreground_insensitive_breeze #232629; -@define-color theme_unfocused_base_color_breeze #ffffff; -@define-color theme_unfocused_bg_color_breeze #eff0f1; -@define-color theme_unfocused_fg_color_breeze #232629; -@define-color theme_unfocused_selected_bg_color_alt_breeze #c2e0f5; -@define-color theme_unfocused_selected_bg_color_breeze #c2e0f5; -@define-color theme_unfocused_selected_fg_color_breeze #232629; -@define-color theme_unfocused_text_color_breeze #232629; -@define-color theme_unfocused_view_bg_color_breeze #f3f3f3; -@define-color theme_unfocused_view_text_color_breeze #aaabac; -@define-color theme_view_active_decoration_color_breeze #3daee9; -@define-color theme_view_hover_decoration_color_breeze #3daee9; -@define-color tooltip_background_breeze #f7f7f7; -@define-color tooltip_border_breeze #c2c3c4; -@define-color tooltip_text_breeze #232629; -@define-color unfocused_borders_breeze #bcbebf; -@define-color unfocused_insensitive_borders_breeze #d2d4d6; -@define-color warning_color_backdrop_breeze #f67400; -@define-color warning_color_breeze #f67400; -@define-color warning_color_insensitive_backdrop_breeze #fbc289; -@define-color warning_color_insensitive_breeze #fbc289; diff --git a/bazzite/gtk-4.0/gtk.css b/bazzite/gtk-4.0/gtk.css deleted file mode 100644 index 15fda59..0000000 --- a/bazzite/gtk-4.0/gtk.css +++ /dev/null @@ -1,2 +0,0 @@ -@import 'colors.css'; -@import 'kde_window_geometry.css'; \ No newline at end of file diff --git a/bazzite/gtk-4.0/settings.ini b/bazzite/gtk-4.0/settings.ini deleted file mode 100644 index f8754a6..0000000 --- a/bazzite/gtk-4.0/settings.ini +++ /dev/null @@ -1,14 +0,0 @@ -[Settings] -gtk-application-prefer-dark-theme=false -gtk-cursor-blink=true -gtk-cursor-blink-time=1000 -gtk-cursor-theme-name=breeze_cursors -gtk-cursor-theme-size=24 -gtk-decoration-layout=icon:minimize,maximize,close -gtk-enable-animations=true -gtk-font-name=Noto Sans, 10 -gtk-icon-theme-name=breeze -gtk-modules=colorreload-gtk-module -gtk-primary-button-warps-slider=true -gtk-sound-theme-name=ocean -gtk-xft-dpi=98304 diff --git a/bazzite/khal-calendar/.gitignore b/bazzite/khal-calendar/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/bazzite/khal-calendar/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/bazzite/khal-calendar/Cargo.lock b/bazzite/khal-calendar/Cargo.lock deleted file mode 100644 index b530709..0000000 --- a/bazzite/khal-calendar/Cargo.lock +++ /dev/null @@ -1,383 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bumpalo" -version = "3.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - -[[package]] -name = "cc" -version = "1.2.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "chrono" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "slab", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "js-sys" -version = "0.3.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" -dependencies = [ - "cfg-if", - "futures-util", - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khal-calendar" -version = "0.1.0" -dependencies = [ - "chrono", - "serde_json", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "wasm-bindgen" -version = "0.2.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/bazzite/khal-calendar/Cargo.toml b/bazzite/khal-calendar/Cargo.toml deleted file mode 100644 index 9799e34..0000000 --- a/bazzite/khal-calendar/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "khal-calendar" -version = "0.1.0" -edition = "2024" - -[dependencies] -chrono = "0.4" -serde_json = "1" - -[lints.rust] -unsafe_code = "warn" - -[lints.clippy] -all = "warn" -pedantic = "warn" diff --git a/bazzite/khal-calendar/README.md b/bazzite/khal-calendar/README.md deleted file mode 100644 index 9e8de6d..0000000 --- a/bazzite/khal-calendar/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# khal-calendar - -Waybar custom calendar module that prints JSON with the current time and a Pango -tooltip. Event days and upcoming events are read from `khal`. - -## Build On Bazzite - -```bash -cd ~/dotfiles/bazzite/khal-calendar -cargo build --release -install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar -``` - -Waybar config should call the compiled binary: - -```jsonc -"exec": "~/.config/waybar/scripts/khal-calendar" -``` diff --git a/bazzite/khal-calendar/src/main.rs b/bazzite/khal-calendar/src/main.rs deleted file mode 100644 index 72d74d6..0000000 --- a/bazzite/khal-calendar/src/main.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::{ - collections::BTreeSet, - process::{Command, Stdio}, - thread::sleep, - time::{Duration, Instant}, -}; - -use chrono::{Datelike, Local, NaiveDate, Timelike}; -use serde_json::json; - -const COMMAND_TIMEOUT: Duration = Duration::from_secs(5); -const MONTH_NAMES: [&str; 13] = [ - "", - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -]; - -fn run_khal(args: &[&str]) -> Option { - 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 { - 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, 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##"{month_name} {year}"##), - r##"Mo Tu We Th Fr Sa Su"##.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##"{day:2}"##) - } else if event_days.contains(&day) { - format!(r##"{day:2}"##) - } else { - format!(r##"{day:2}"##) - }; - 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\nUpcoming\n{events}"##) - }; - - println!( - "{}", - json!({ - "text": format!("{:02}:{:02}", now.hour(), now.minute()), - "tooltip": tooltip, - "alt": today.format("%Y-%m-%d").to_string(), - }) - ); -} diff --git a/bazzite/mail-counter/.gitignore b/bazzite/mail-counter/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/bazzite/mail-counter/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/bazzite/mail-counter/Cargo.lock b/bazzite/mail-counter/Cargo.lock deleted file mode 100644 index 36e96e7..0000000 --- a/bazzite/mail-counter/Cargo.lock +++ /dev/null @@ -1,213 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "bitflags" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" - -[[package]] -name = "cc" -version = "1.2.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashlink" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" -dependencies = [ - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "libsqlite3-sys" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "mail-counter" -version = "0.1.0" -dependencies = [ - "rusqlite", - "serde_json", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rusqlite" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" -dependencies = [ - "bitflags", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/bazzite/mail-counter/Cargo.toml b/bazzite/mail-counter/Cargo.toml deleted file mode 100644 index 6a5c456..0000000 --- a/bazzite/mail-counter/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "mail-counter" -version = "0.1.0" -edition = "2024" - -[dependencies] -rusqlite = { version = "0.37", features = ["bundled"] } -serde_json = "1" - -[lints.rust] -unsafe_code = "warn" - -[lints.clippy] -all = "warn" -pedantic = "warn" diff --git a/bazzite/mail-counter/README.md b/bazzite/mail-counter/README.md deleted file mode 100644 index 5cc118e..0000000 --- a/bazzite/mail-counter/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# mail-counter - -Waybar custom mail module for Thunderbird. It reads Thunderbird's -`global-messages-db.sqlite` and prints JSON for Waybar. - -## Build On Bazzite - -```bash -cd ~/dotfiles/bazzite/mail-counter -cargo build --release -install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail -``` - -Waybar config should call the compiled binary: - -```jsonc -"exec": "~/.config/waybar/scripts/mail" -``` diff --git a/bazzite/mail-counter/src/main.rs b/bazzite/mail-counter/src/main.rs deleted file mode 100644 index e49a56d..0000000 --- a/bazzite/mail-counter/src/main.rs +++ /dev/null @@ -1,113 +0,0 @@ -use std::{ - env, fs, - path::{Path, PathBuf}, -}; - -use rusqlite::{Connection, OpenFlags}; -use serde_json::{Value, json}; - -const MAIL_ICON: &str = "\u{f01ee}"; - -fn thunderbird_profile() -> Option { - 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::>(); - profiles.sort(); - profiles.into_iter().next() - }) -} - -fn open_readonly_database(path: &Path) -> rusqlite::Result { - Connection::open_with_flags( - path, - OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX, - ) -} - -fn unread_from_messages(conn: &Connection) -> rusqlite::Result { - 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 { - conn.query_row( - "SELECT SUM(numNewMessages) FROM folderlocations WHERE numNewMessages > 0", - [], - |row| row.get::<_, Option>(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))); -} diff --git a/bazzite/niri/config.kdl b/bazzite/niri/config.kdl deleted file mode 100644 index 3177dbf..0000000 --- a/bazzite/niri/config.kdl +++ /dev/null @@ -1,625 +0,0 @@ -debug { - // preview-render "screencast" - // preview-render "screen-capture" - // dbus-interfaces-in-non-session-instances - // wait-for-frame-completion-before-queueing - // enable-overlay-planes - disable-cursor-plane - // disable-direct-scanout - // render-drm-device "/dev/dri/renderD129" - // render-drm-device "/dev/dri/card1" - // enable-color-transformations-capability - // emulate-zero-presentation-time -} - -input { - keyboard { - xkb { - - } - - repeat-delay 500 - repeat-rate 30 - - // track-layout "window" - } - - touchpad { - tap - // dwt - // dwtp - natural-scroll - accel-speed 0.4 - // click-method "clickfinger" - // accel-profile "flat" - // tap-button-map "left-middle-right" - } - - mouse { - // natural-scroll - // accel-speed -1.0 - // accel-profile "flat" - } - - tablet { - // map-to-output "eDP-1" - // map-to-output "HDMI-A-1" - } - - // disable-power-key-handling - // warp-mouse-to-focus - // focus-follows-mouse - // workspace-auto-back-and-forth -} - -output "winit" { - // scale 2.0 - // scale 3.0 - // transform "flipped-90" - position x=100 y=200 -} - -output "DP-1" { - // off - - scale 1.0 - // transform "90" - position x=0 y=0 - // mode "1920x1200" - mode "2560x1440@170.001" - // mode "1280x1024" - // mode "1280x720" - // mode "640x480" - - // variable-refresh-rate -} - -layout { - focus-ring { - off - width 2 - // catppuccin-mocha Sapphire - active-color "#74c7ec" - // catppuccin-mocha Surface2 - inactive-color "#585b70" - - // active-gradient from="#80c8ff" to="#bbddff" angle=45 - } - - border { - // off - width 2 - // width 128 - - // active-color "#f38ba8" - // inactive-color "#585b70" - - active-gradient from="#f38ba8" to="#f9e2af" angle=45 relative-to="workspace-view" - inactive-gradient from="#585b70" to="#7f849c" angle=45 relative-to="workspace-view" - - // inactive-gradient from="green" to="lightblue" angle=45 relative-to="workspace-view" - // active-gradient from="#f00" to="#0f0" angle=90 - - // active-gradient from="yellow" to="red" angle=45 relative-to="workspace-view" - // inactive-gradient from="yellow" to="red" angle=45 - } - - preset-column-widths { - proportion 0.3333333333333333 - proportion 0.5 - proportion 0.66667 - // proportion 0.25 - // fixed 1000 - } - - default-column-width { proportion 0.3333333333333333; } - // default-column-width { } - - gaps 4 - - struts { - // left 64 - // right 64 - // top 44 - // bottom 64 - // top 64 - } - - // center-focused-column "on-overflow" - // center-focused-column "always" -} - -cursor { - // xcursor-theme "breeze_cursors" - // xcursor-theme "arstieonart" - // xcursor-size 48 -} - -prefer-no-csd - -// spawn-at-startup "alacritty" "-e" "fish" - -environment { - // GSK_RENDERER "cairo" - // WAYLAND_DISPLAY null -} - -// screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" -spawn-at-startup "sh" "-c" "exec ~/.local/bin/swaybg -i ~/Pictures/Wallpapers/image.png -m fill" -spawn-at-startup "waybar" -hotkey-overlay { - // skip-at-startup -} - -animations { - // off - // slowdown 10.0 - // slowdown 4.0 - // slowdown 2.0 - // slowdown 1.5 - - workspace-switch { - // off - // duration-ms 2500 - // curve "ease-out-cubic" - // spring damping-ratio=1.0 stiffness=1000 epsilon=0.0001 - } - - window-open { - // off - // duration-ms 2500 - // curve "ease-out-expo" - // spring damping-ratio=0.8 stiffness=1000 epsilon=0.0001 - } - - window-close { - // off - // duration-ms 2500 - // curve "ease-out-cubic" - // spring damping-ratio=0.8 stiffness=1000 epsilon=0.0001 - } - - horizontal-view-movement { - // off - // duration-ms 500 - // curve "ease-out-cubic" - // spring damping-ratio=1.0 stiffness=20 epsilon=0.00001 - // spring damping-ratio=10.0 stiffness=800 epsilon=0.0001 - } - - window-movement { - // off - // duration-ms 750 - // curve "ease-out-cubic" - // spring damping-ratio=1.0 stiffness=20 epsilon=0.00001 - // spring damping-ratio=0.2 stiffness=800 epsilon=0.0001 - } - - window-resize { - // off - // duration-ms 500 - // duration-ms 2500 - // curve "ease-out-cubic" - // spring damping-ratio=0.2 stiffness=800 epsilon=0.0001 - - custom-shader r" - vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) { - vec3 coords_next_geo = niri_curr_geo_to_next_geo * coords_curr_geo; - vec3 coords_prev_geo = niri_curr_geo_to_prev_geo * coords_curr_geo; - - vec3 coords_crop = niri_geo_to_tex_next * coords_next_geo; - vec3 coords_stretch = niri_geo_to_tex_next * coords_curr_geo; - vec3 coords_stretch_prev = niri_geo_to_tex_prev * coords_curr_geo; - - // We can crop if the current window size is smaller than the next window - // size. One way to tell is by comparing to 1.0 the X and Y scaling - // coefficients in the current-to-next transformation matrix. - bool can_crop_by_x = niri_curr_geo_to_next_geo[0][0] <= 1.0; - bool can_crop_by_y = niri_curr_geo_to_next_geo[1][1] <= 1.0; - bool crop = can_crop_by_x && can_crop_by_y; - - vec4 color; - - if (crop) { - // However, when we crop, we also want to crop out anything outside the - // current geometry. This is because the area of the shader is unspecified - // and usually bigger than the current geometry, so if we don't fill pixels - // outside with transparency, the texture will leak out. - // - // When stretching, this is not an issue because the area outside will - // correspond to client-side decoration shadows, which are already supposed - // to be outside. - if (coords_curr_geo.x < 0.0 || 1.0 < coords_curr_geo.x || - coords_curr_geo.y < 0.0 || 1.0 < coords_curr_geo.y) { - color = vec4(0.0); - } else { - color = texture2D(niri_tex_next, coords_crop.st); - } - } else { - // If we can't crop, then crossfade. - color = texture2D(niri_tex_next, coords_stretch.st); - vec4 color_prev = texture2D(niri_tex_prev, coords_stretch_prev.st); - color = mix(color_prev, color, niri_clamped_progress); - } - - return color; - } - " - } - - config-notification-open-close { - // off - // duration-ms 250 - // curve "ease-out-cubic" - // spring damping-ratio=0.1 stiffness=1000 epsilon=0.001 - } -} - -window-rule { - // match app-id="Alacritty" - // match app-id="Adwaita" - // opacity 0.9 - // opacity 0.5 - // opacity 0.98 - - // open-on-output "eDP-1" - // default-column-width { proportion 0.5; } - // default-column-width { fixed 400; } - // default-column-width {} - // open-maximized true - // open-fullscreen true - // block-out-from "screencast" - - // min-width 400 - // max-width 400 - // min-height 400 - // max-height 400 - - focus-ring { - // on - // active-gradient from="red" to="green" - // active-color "lightgreen" - // width 1 - } - - border { - // off - // on - // width 12 - // width 0 - // active-color "#ff808080" - // active-color "red" - } - - // draw-border-with-background true - // draw-border-with-background false - - // geometry-corner-radius 12 24 32 64 - // geometry-corner-radius 999 - // geometry-corner-radius 1 - geometry-corner-radius 6 - clip-to-geometry true -} - -/-window-rule { - match app-id="Adwaita" - // opacity 0.5 - block-out-from "screencast" - geometry-corner-radius 12 - clip-to-geometry false - border { - // off - width 12 - } -} - -/-window-rule { - match app-id="terminal" - clip-to-geometry false - geometry-corner-radius 8 8 0 0 - border { - // width 4 - } -} - -/-window-rule { - match app-id="code" - // opacity 0.98 - border { - // off - } -} - -/-window-rule { - match app-id="weston." - // block-out-from "screencast" - geometry-corner-radius 12 24 32 64 - // geometry-corner-radius 999 - clip-to-geometry true -} - -// window-rule { -// match app-id="Alacritty" -// geometry-corner-radius 12 12 0 0 -// border { -// width 2 -// } -// } - -window-rule { - match title="simple-egl" - // min-width 128 - // max-width 128 - // min-height 128 - // max-height 128 - // match is-focused=true - // match is-active=false - // opacity 0.9 - // block-out-from "screencast" - // block-out-from "screen-capture" - // min-width 1000 - draw-border-with-background false - // match app-id="mpv" - // open-on-output "HDMI-A-1" - // open-maximized true - // default-column-width { proportion 0.5; } - // open-fullscreen false -} - -window-rule { - match title="khal-popup" - open-floating true - default-floating-position x=0 y=0 relative-to="top-right" - default-column-width { fixed 600; } - default-window-height { fixed 400; } -} - -window-rule { - match is-active=false - // opacity 0.95 -} - -window-rule { - match app-id=r#"^org\.telegram\.desktop$"# title="^Media viewer$" - open-fullscreen false - default-column-width { proportion 0.5; } -} - -window-rule { - match app-id=r#"^org\.wezfurlong\.wezterm$"# - match app-id="^mpv$" - default-column-width {} -} - -// Qt used by OBS doesn't signal min size yet, so do it manually. -window-rule { - match app-id=r#"^com\.obsproject\.Studio$"# - min-width 876 -} - -window-rule { - match app-id="^blender$" - match app-id="^gimp" - default-column-width { fixed 1200; } -} - -window-rule { - match app-id="^obsidian$" - default-column-width { fixed 1000; } -} - -window-rule { - match app-id=r#"^org\.mozilla\.firefox$"# - match app-id=r#"^org\.telegram\.desktop$"# - exclude app-id=r#"^org\.telegram\.desktop$"# title="^Media viewer$" - - open-on-output "DP-2" -} - -window-rule { - match app-id=r#"^org\.mozilla\.firefox$"# - - default-column-width { proportion 0.66667; } -} - -window-rule { - match app-id=r#"^org\.keepassxc\.KeePassXC$"# - match app-id=r#"^org\.gnome\.World\.Secrets$"# - match app-id=r#"^org\.telegram\.desktop$"# - - // Doesn't quite work: Firefox changes the title one frame early. - match app-id=r#"^org\.mozilla\.firefox$"# title="- Gmail " - match app-id=r#"^org\.mozilla\.firefox$"# title="^Google Calendar " - match app-id=r#"^org\.mozilla\.firefox$"# title="Todoist " - match app-id=r#"^org\.mozilla\.firefox$"# title=r#"^GNOME( \*)? \| "# - match app-id=r#"^org\.mozilla\.firefox$"# title=r#"^Element "# - match app-id=r#"^org\.mozilla\.firefox$"# title=r#"Discord \| "# - - block-out-from "screencast" - // block-out-from "screen-capture" - - border { - // active-color "red" - } -} - -binds { - Mod+Shift+Slash { show-hotkey-overlay; } - - Mod+Shift+C { spawn "sh" "-c" "t env DISPLAY=:0 xsel -ob | wl-copy"; } - Mod+Shift+V { spawn "sh" "-c" "wl-paste -n | t env DISPLAY=:0 xsel -ib"; } - - // Mod+T { spawn "sh" "-c" "alacritty msg create-window -e fish -C t || alacritty -e fish -C t"; } - Mod+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; } - Mod+Shift+T { spawn "alacritty"; } - // Mod+Shift+T { spawn "sh" "-c" "alacritty msg create-window || alacritty"; } - // Mod+Return { spawn "~/arst"; } - // Mod+T { spawn "flatpak" "run" "org.gnome.Ptyxis.Devel" "-s"; } - // Mod+T { spawn "~/.local/bin/spawn-ptyxis.sh"; } - // Mod+T { spawn "bash" "-c" "notify-send hello && exec alacritty"; } - // Mod+T { spawn "kgx" "-e" "fish -C t"; } - Mod+D { spawn "fuzzel"; } - Mod+H { spawn "nautilus"; } - Super+Alt+L allow-when-locked=true { spawn "swaylock"; } - - Mod+W { spawn "sh" "-c" "t mpv --pause $(wl-paste)"; } - Super+Alt+H { spawn "refresh.sh" "144"; } - Super+Alt+Comma { spawn "refresh.sh" "120"; } - - XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"; } - XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"; } - XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; } - XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; } - - Mod+Q { close-window; } - Mod+BackSpace { close-window; } - - Mod+M { focus-column-left; } - Mod+N { focus-window-down; } - Mod+E { focus-window-up; } - Mod+I { focus-column-right; } - Mod+Left { focus-column-left; } - Mod+Down { focus-window-down; } - Mod+Up { focus-window-up; } - Mod+Right { focus-column-right; } - - Mod+Ctrl+M { move-column-left; } - Mod+Ctrl+N { move-window-down; } - Mod+Ctrl+E { move-window-up; } - Mod+Ctrl+I { move-column-right; } - Mod+Ctrl+Left { move-column-left; } - Mod+Ctrl+Down { move-window-down; } - Mod+Ctrl+Up { move-window-up; } - Mod+Ctrl+Right { move-column-right; } - - Mod+Home { focus-column-first; } - Mod+End { focus-column-last; } - Mod+Ctrl+Home { move-column-to-first; } - Mod+Ctrl+End { move-column-to-last; } - - Mod+Shift+M { focus-monitor-left; } - Mod+Shift+N { focus-monitor-down; } - Mod+Shift+E { focus-monitor-up; } - Mod+Shift+I { focus-monitor-right; } - Mod+Shift+Left { focus-monitor-left; } - Mod+Shift+Down { focus-monitor-down; } - Mod+Shift+Up { focus-monitor-up; } - Mod+Shift+Right { focus-monitor-right; } - - Mod+Shift+Ctrl+M { move-column-to-monitor-left; } - Mod+Shift+Ctrl+N { move-column-to-monitor-down; } - Mod+Shift+Ctrl+E { move-column-to-monitor-up; } - Mod+Shift+Ctrl+I { move-column-to-monitor-right; } - Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } - Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } - Mod+Shift+Ctrl+Up { move-column-to-monitor-up; } - Mod+Shift+Ctrl+Right { move-column-to-monitor-right; } - - Mod+Shift+Alt+M { move-workspace-to-monitor-left; } - Mod+Shift+Alt+N { move-workspace-to-monitor-down; } - Mod+Shift+Alt+E { move-workspace-to-monitor-up; } - Mod+Shift+Alt+I { move-workspace-to-monitor-right; } - Mod+Shift+Alt+Left { move-workspace-to-monitor-left; } - Mod+Shift+Alt+Down { move-workspace-to-monitor-down; } - Mod+Shift+Alt+Up { move-workspace-to-monitor-up; } - Mod+Shift+Alt+Right { move-workspace-to-monitor-right; } - - Mod+L { focus-workspace-down; } - Mod+U { focus-workspace-up; } - Mod+Page_Down { focus-workspace-down; } - Mod+Page_Up { focus-workspace-up; } - Mod+Ctrl+L { move-column-to-workspace-down; } - Mod+Ctrl+U { move-column-to-workspace-up; } - Mod+Ctrl+Page_Down { move-column-to-workspace-down; } - Mod+Ctrl+Page_Up { move-column-to-workspace-up; } - - Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } - Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } - Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } - Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } - - Mod+WheelScrollRight { focus-column-right; } - Mod+WheelScrollLeft { focus-column-left; } - Mod+Ctrl+WheelScrollRight { move-column-right; } - Mod+Ctrl+WheelScrollLeft { move-column-left; } - - Mod+Shift+WheelScrollDown { focus-column-right; } - Mod+Shift+WheelScrollUp { focus-column-left; } - Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } - Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } - - Mod+TouchpadScrollUp allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; } - Mod+TouchpadScrollDown allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; } - // Mod+TouchpadScrollLeft { focus-column-left; } - // Mod+TouchpadScrollRight { focus-column-right; } - - Mod+Shift+L { move-workspace-down; } - Mod+Shift+U { move-workspace-up; } - Mod+Shift+Page_Down { move-workspace-down; } - Mod+Shift+Page_Up { move-workspace-up; } - - Mod+1 { focus-workspace 1; } - Mod+2 { focus-workspace 2; } - Mod+3 { focus-workspace 3; } - Mod+4 { focus-workspace 4; } - Mod+5 { focus-workspace 5; } - Mod+6 { focus-workspace 6; } - Mod+7 { focus-workspace 7; } - Mod+8 { focus-workspace 8; } - Mod+9 { focus-workspace 9; } - Mod+Ctrl+1 { move-column-to-workspace 1; } - Mod+Ctrl+2 { move-column-to-workspace 2; } - Mod+Ctrl+3 { move-column-to-workspace 3; } - Mod+Ctrl+4 { move-column-to-workspace 4; } - Mod+Ctrl+5 { move-column-to-workspace 5; } - Mod+Ctrl+6 { move-column-to-workspace 6; } - Mod+Ctrl+7 { move-column-to-workspace 7; } - Mod+Ctrl+8 { move-column-to-workspace 8; } - Mod+Ctrl+9 { move-column-to-workspace 9; } - - // Mod+Tab { focus-workspace-previous; } - - Mod+Comma { consume-window-into-column; } - Mod+Period { expel-window-from-column; } - - Mod+BracketLeft { consume-or-expel-window-left; } - Mod+BracketRight { consume-or-expel-window-right; } - - Mod+R { switch-preset-column-width; } - Mod+F { maximize-column; } - Mod+Shift+F { fullscreen-window; } - Mod+C { center-column; } - - Mod+Minus { set-column-width "-10%"; } - Mod+Equal { set-column-width "+10%"; } - Mod+Ctrl+Minus { set-column-width "-1"; } - Mod+Ctrl+Equal { set-column-width "+1"; } - - Mod+Shift+Minus { set-window-height "-10%"; } - Mod+Shift+Equal { set-window-height "+10%"; } - Mod+Shift+Ctrl+Minus { set-window-height "-1"; } - Mod+Shift+Ctrl+Equal { set-window-height "+1"; } - - Mod+0 { set-column-width "960"; } - Mod+Shift+0 { set-window-height "540"; } - Mod+Alt+0 { set-column-width "1280"; } - Mod+Shift+Alt+0 { set-window-height "720"; } - Mod+Ctrl+0 { set-column-width "1920"; } - Mod+Shift+Ctrl+0 { set-window-height "1080"; } - - Mod+Space { switch-layout "next"; } - Mod+Shift+Space { switch-layout "prev"; } - - Print { screenshot; } - Ctrl+Print { screenshot-screen; } - Alt+Print { screenshot-window; } - - Mod+P { screenshot; } - - Mod+Shift+Y { quit; } - Mod+Shift+P { power-off-monitors; } - - Mod+Shift+Ctrl+T { toggle-debug-tint; } - Mod+Shift+Ctrl+O { debug-toggle-opaque-regions; } - Mod+Shift+Ctrl+D { debug-toggle-damage; } -} diff --git a/bazzite/screenshots/waybar-icons-fixed.png b/bazzite/screenshots/waybar-icons-fixed.png deleted file mode 100644 index bbb94e6..0000000 Binary files a/bazzite/screenshots/waybar-icons-fixed.png and /dev/null differ diff --git a/bazzite/wallpapers/image.png b/bazzite/wallpapers/image.png deleted file mode 100644 index 213256f..0000000 Binary files a/bazzite/wallpapers/image.png and /dev/null differ diff --git a/bazzite/waybar/config.jsonc b/bazzite/waybar/config.jsonc deleted file mode 100644 index 9711ce1..0000000 --- a/bazzite/waybar/config.jsonc +++ /dev/null @@ -1,179 +0,0 @@ -// -*- mode: jsonc -*- -{ - "layer": "top", - "height": 32, - "spacing": 8, - - "modules-left": [ - "niri/workspaces" - ], - "modules-center": [ - "niri/window" - ], - "modules-right": [ - "privacy", - "custom/mail", - "custom/weather", - "pulseaudio", - "network", - "niri/language", - "power-profiles-daemon", - "cpu", - "memory", - "temperature", - "custom/gpu", - "disk", - "custom/calendar", - "tray" - ], - - "niri/workspaces": { - "format": "{index}" - }, - - "niri/window": { - "format": "{}", - "max-length": 50, - "align": 0.5, - "justify": "center" - }, - - "niri/language": { - "format": "{short}", - "align": 0.5, - "justify": "center" - }, - - "privacy": { - "icon-spacing": 4, - "icon-size": 16, - "transition-duration": 250, - "modules": [ - { "type": "screenshare" }, - { "type": "audio-in" }, - { "type": "audio-out" } - ] - }, - - "custom/mail": { - "format": "{}", - "return-type": "json", - "exec": "~/.config/waybar/scripts/mail", - "interval": 60, - "tooltip": true, - "on-click": "flatpak run org.mozilla.Thunderbird", - "align": 0.5, - "justify": "center" - }, - - "custom/weather": { - "format": "{}", - "return-type": "json", - "exec": "~/.config/waybar/scripts/weather.sh", - "interval": 900, - "tooltip": true, - "align": 0.5, - "justify": "center" - }, - - "custom/gpu": { - "format": "{}", - "return-type": "json", - "exec": "~/.config/waybar/scripts/gpu.sh", - "interval": 5, - "tooltip": true, - "align": 0.5, - "justify": "center" - }, - - "disk": { - "format": " {percentage_used}%", - "path": "/", - "tooltip-format": "{used} / {total} ({percentage_used}%)", - "align": 0.5, - "justify": "center" - }, - - "tray": { - "spacing": 10 - }, - - "custom/calendar": { - "format": " {}", - "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, - "align": 0.5, - "justify": "center" - }, - - "memory": { - "format": " {}%", - "align": 0.5, - "justify": "center" - }, - - "temperature": { - "critical-threshold": 80, - "format": " {temperatureC}°C", - "align": 0.5, - "justify": "center" - }, - - "network": { - "format-wifi": "{icon}", - "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": "", - "align": 0.5, - "justify": "center" - }, - - "pulseaudio": { - "format": "{icon} {volume}% {format_source}", - "format-bluetooth": "{icon} {volume}% {format_source}", - "format-bluetooth-muted": " {format_source}", - "format-muted": " {format_source}", - "format-source": "{volume}%", - "format-source-muted": "", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click": "pavucontrol", - "align": 0.5, - "justify": "center" - }, - - "power-profiles-daemon": { - "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", - "tooltip": true, - "align": 0.5, - "justify": "center", - "format-icons": { - "default": "", - "performance": "", - "balanced": "", - "power-saver": "" - } - } -} diff --git a/bazzite/waybar/scripts/gpu.sh b/bazzite/waybar/scripts/gpu.sh deleted file mode 100755 index fb870d1..0000000 --- a/bazzite/waybar/scripts/gpu.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null) -if [ -z "$data" ]; then - echo '{"text": "GPU N/A", "tooltip": "nvidia-smi not available"}' - exit 0 -fi -usage=$(echo "$data" | cut -d',' -f1 | tr -d ' ') -temp=$(echo "$data" | cut -d',' -f2 | tr -d ' ') -echo "{\"text\": \"GPU ${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}" diff --git a/bazzite/waybar/scripts/weather.sh b/bazzite/waybar/scripts/weather.sh deleted file mode 100755 index e37ecd7..0000000 --- a/bazzite/waybar/scripts/weather.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -weather=$(curl -s "wttr.in/?format=%c%t" 2>/dev/null) -if [ -z "$weather" ] || echo "$weather" | grep -q "Unknown"; then - echo '{"text": "N/A", "tooltip": "Weather unavailable"}' - exit 0 -fi -tooltip=$(curl -s "wttr.in/?format=%l:+%C+%t+%w+%h" 2>/dev/null) -echo "{\"text\": \"${weather}\", \"tooltip\": \"${tooltip}\"}" diff --git a/bazzite/waybar/style.css b/bazzite/waybar/style.css deleted file mode 100644 index 4cffa06..0000000 --- a/bazzite/waybar/style.css +++ /dev/null @@ -1,262 +0,0 @@ -/* Catppuccin Latte */ -@define-color rosewater #dc8a78; -@define-color flamingo #dd7878; -@define-color pink #ea76cb; -@define-color mauve #8839ef; -@define-color red #d20f39; -@define-color maroon #e64553; -@define-color peach #fe640b; -@define-color yellow #df8e1d; -@define-color green #40a02b; -@define-color teal #179299; -@define-color sky #04a5e5; -@define-color sapphire #209fb5; -@define-color blue #1e66f5; -@define-color lavender #7287fd; -@define-color text #4c4f69; -@define-color subtext1 #5c5f77; -@define-color subtext0 #6c6f85; -@define-color overlay2 #7c7f93; -@define-color overlay1 #8c8fa1; -@define-color overlay0 #9ca0b0; -@define-color surface2 #acb0be; -@define-color surface1 #bcc0cc; -@define-color surface0 #ccd0da; -@define-color base #eff1f5; -@define-color mantle #e6e9ef; -@define-color crust #dce0e8; - -* { - font-family: 'Noto Sans Mono', 'Symbols Nerd Font Mono', 'Symbols Nerd Font', 'Font Awesome 6 Free', monospace; - font-size: 15px; - font-weight: bold; -} - -window#waybar { - background-color: rgba(30, 30, 46, 0.72); - color: @text; - transition-property: background-color; - transition-duration: .5s; -} - -window#waybar.hidden { - opacity: 0.2; -} - -button { - box-shadow: inset 0 -3px transparent; - border: none; - border-radius: 16px; -} - -button:hover { - background: inherit; - box-shadow: inset 0 -2px @blue; -} - -/* Workspaces */ -#workspaces button { - min-height: 24px; - padding: 4px 8px; - background-color: #000000; - color: @overlay2; - border-radius: 16px; -} - -#workspaces button:hover { - background: #000000; -} - -#workspaces button.active { - color: @blue; - box-shadow: inset 0 -2px @blue; -} - -#workspaces button.urgent { - background-color: #000000; - color: @base; -} - -/* Common module styling */ -#window, -#custom-calendar, -#cpu, -#memory, -#disk, -#temperature, -#network, -#pulseaudio, -#wireplumber, -#tray, -#power-profiles-daemon, -#language, -#custom-gpu, -#custom-weather, -#privacy { - min-height: 24px; - padding: 4px 8px; - background-color: #000000; - border-radius: 16px; - color: @text; -} - -#workspaces button label, -#window label, -#custom-calendar label, -#cpu label, -#memory label, -#disk label, -#temperature label, -#network label, -#pulseaudio label, -#wireplumber label, -#tray label, -#power-profiles-daemon label, -#language label, -#custom-gpu label, -#custom-weather label, -#privacy label { - min-height: 24px; - padding: 0; - margin: 0; -} - -#window, -#workspaces { - margin: 0 4px; -} - -#window { - color: @text; -} - -/* Calendar/Clock */ -#custom-calendar { - color: @blue; - font-weight: bold; -} - -/* CPU */ -#cpu { - color: @green; -} - -/* Memory */ -#memory { - color: @mauve; -} - -/* Temperature */ -#temperature { - color: @peach; -} - -#temperature.critical { - color: @red; -} - -/* Network */ -#network { - color: @sapphire; - font-size: 20px; -} - -#network.disconnected { - color: @red; -} - -/* Pulseaudio */ -#pulseaudio { - color: @yellow; -} - -#pulseaudio.muted { - color: @overlay1; -} - -/* Language */ -#language { - color: @teal; - font-weight: bold; -} - -/* Power profiles */ -#power-profiles-daemon { - color: @subtext0; -} - -#power-profiles-daemon.performance { - color: @red; -} - -#power-profiles-daemon.balanced { - color: @blue; -} - -#power-profiles-daemon.power-saver { - color: @green; -} - -/* Mail */ -#custom-mail { - color: @lavender; -} - -#custom-mail.unread { - color: @red; -} - -/* Disk */ -#disk { - color: @flamingo; -} - -/* GPU */ -#custom-gpu { - color: @green; -} - -/* Weather */ -#custom-weather { - color: @sky; -} - -/* Privacy */ -#privacy { - background-color: transparent; - padding: 0; -} - -#privacy-item { - min-height: 24px; - padding: 4px 8px; - color: @base; - background-color: #000000; - border-radius: 16px; -} - -#privacy-item.screenshare { - background-color: #000000; -} - -#privacy-item.audio-in { - background-color: #000000; -} - -#privacy-item.audio-out { - background-color: #000000; -} - -/* Tray */ -#tray { - color: @text; -} - -#tray > .passive { - -gtk-icon-effect: dim; -} - -#tray > .needs-attention { - -gtk-icon-effect: highlight; - color: @red; -} diff --git a/bazzite/xsettingsd/xsettingsd.conf b/bazzite/xsettingsd/xsettingsd.conf deleted file mode 100644 index 327b162..0000000 --- a/bazzite/xsettingsd/xsettingsd.conf +++ /dev/null @@ -1,17 +0,0 @@ -Gdk/UnscaledDPI 98304 -Gdk/WindowScalingFactor 1 -Gtk/EnableAnimations 1 -Gtk/DecorationLayout "icon:minimize,maximize,close" -Net/ThemeName "" -Gtk/PrimaryButtonWarpsSlider 1 -Gtk/ToolbarStyle 3 -Gtk/MenuImages 1 -Gtk/ButtonImages 1 -Net/CursorBlinkTime 1000 -Net/CursorBlink 1 -Gtk/CursorThemeSize 24 -Gtk/CursorThemeName "breeze_cursors" -Net/SoundThemeName "ocean" -Net/IconThemeName "breeze" -Gtk/FontName "Noto Sans, 10" - diff --git a/fedora/README.md b/fedora/README.md deleted file mode 100644 index 9661203..0000000 --- a/fedora/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# Конфиги рабочего стола Fedora - -Эта папка содержит профиль Fedora KDE/Workstation, где основной рабочей -Wayland-сессией становится Niri. Профиль получен из старого `bazzite/`, но -адаптирован под обычную mutable Fedora: пакеты ставятся через `dnf`, Steam -запускается обычным `/usr/bin/steam`, а локальные Bazzite helpers не требуются. - -## Что здесь настроено - -| Путь | Назначение | -|---|---| -| `niri/config.kdl` | Конфиг Niri: монитор `DP-1`, ввод, раскладка окон, автозапуск, правила окон, хоткеи. | -| `waybar/` | Верхняя панель: конфиг, CSS в стиле Catppuccin и custom-модули. | -| `waybar/scripts/gpu.sh` | Модуль Waybar для загрузки и температуры NVIDIA GPU через `nvidia-smi`. | -| `waybar/scripts/weather.sh` | Модуль Waybar с погодой через `wttr.in`. | -| `khal-calendar/` | Rust-версия календарного модуля Waybar. | -| `mail-counter/` | Rust-модуль Waybar для счетчика непрочитанных писем Thunderbird. | -| `calendar-mail-popup-notes.md` | Набросок UX и архитектуры для собственного calendar/mail popup из Waybar. | -| `fuzzel/fuzzel.ini` | Тема лаунчера Fuzzel на цветах Catppuccin Latte. | -| `btop/btop.conf` | Настройки системного монитора btop. | -| `glow/glow.yml` | Настройки терминального Markdown-viewer Glow. | -| `gtk-3.0/`, `gtk-4.0/` | GTK-настройки и цветовые файлы Breeze/Catppuccin. | -| `xsettingsd/xsettingsd.conf` | Настройки GTK, курсора, иконок, шрифта и DPI для X11/XWayland-приложений. | -| `environment.d/intel-gtk-fix.conf` | Переменная окружения сессии: `GSK_RENDERER=gl`. | -| `autostart/steam.desktop` | Автозапуск Steam через обычный Fedora Steam. | -| `wallpapers/raspberry.png` | Текущая картинка рабочего стола для `swaybg`. | - -## Ожидаемые программы - -```bash -sudo dnf install -y \ - niri waybar fuzzel alacritty swaybg swaylock \ - btop glow xsettingsd pavucontrol xsel mpv nautilus \ - khal vdirsyncer thunderbird rustup cargo -``` - -Также ожидается уже настроенный NVIDIA-драйвер с рабочим `nvidia-smi`. - -## Установка - -Подключить директории в `~/.config`: - -```bash -for dir in niri fuzzel waybar btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do - ln -sfn ~/dotfiles/fedora/$dir ~/.config/$dir -done -mkdir -p ~/Pictures/Wallpapers -ln -sfn ~/dotfiles/fedora/wallpapers/raspberry.png ~/Pictures/Wallpapers/raspberry.png -``` - -Если репозиторий лежит не в `~/dotfiles`, путь нужно поправить. - -## Сборка календарного модуля - -```bash -cd ~/dotfiles/fedora/khal-calendar -cargo build --release -install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar -``` - -## Сборка почтового модуля - -```bash -cd ~/dotfiles/fedora/mail-counter -cargo build --release -install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail -``` - -Модуль читает `global-messages-db.sqlite` из профиля Thunderbird и печатает JSON -для `custom/mail` в Waybar. - -## Fedora-specific отличия от Bazzite - -- Steam запускается через `/usr/bin/steam`, не через `/usr/bin/bazzite-steam`. -- Wallpaper запускается через `swaybg` из `$PATH`, не через `~/.local/bin/swaybg`. -- Hotkeys на `refresh.sh` отключены, потому что этого локального helper пока нет. -- Clipboard hotkeys больше не зависят от локальной команды `t`. -- Firefox/Telegram правила Niri отправляют окна на `DP-1`, текущий подключенный - выход на этой Fedora-машине. - -## Перезагрузка - -После изменения конфига или CSS Waybar: - -```bash -pkill -SIGUSR2 waybar -``` - -Если Waybar не подхватил изменения, нужно перезапустить Waybar вручную или -перезапустить Niri-сессию. diff --git a/fedora/alacritty/alacritty.toml b/fedora/alacritty/alacritty.toml new file mode 100644 index 0000000..10c9c87 --- /dev/null +++ b/fedora/alacritty/alacritty.toml @@ -0,0 +1,6 @@ +[window] +# Let the wallpaper show through without making terminal text hard to read. +opacity = 0.8 + +[font] +normal = { family = "JetBrainsMono Nerd Font Mono" } diff --git a/fedora/calendar-mail-popup-notes.md b/fedora/calendar-mail-popup-notes.md deleted file mode 100644 index e8dd00a..0000000 --- a/fedora/calendar-mail-popup-notes.md +++ /dev/null @@ -1,191 +0,0 @@ -# Calendar + Mail Popup Notes - -Заметка по идее компактного календарно-почтового инструмента для Fedora + Niri + -Waybar. - -## Цель - -Нужны две связанные поверхности: - -1. Понятное решение в `waybar`, откуда можно быстро открыть календарь и увидеть - нужную информацию. -2. Отдельное компактное `tool-window` / popup-окно с календарем и мини-почтой. - -Это не должен быть полноценный тяжелый PIM-комбайн на первом этапе. Основной -приоритет — быстрый обзор и быстрые действия. - -## Что нужно уметь - -### В Waybar - -- Кликнуть по модулю. -- Увидеть календарную информацию без переключения в большой клиент. -- Быстро понять: - - что сегодня; - - что дальше по неделе; - - есть ли ближайшие события; - - есть ли непрочитанная почта. - -### В popup/tool-window - -- Посмотреть календарь на неделю и месяц. -- Увидеть список ближайших событий. -- Создать событие. -- Иметь мини-почту как обзор, а не как полноценный mail client. - -## Ограничения текущего Waybar - -Встроенный `clock` модуль Waybar умеет: - -- показывать месяц/год; -- переключать режимы; -- листать календарь; -- запускать команды по клику. - -Но встроенный календарь Waybar — только display layer: - -- он не показывает реальные CalDAV / Nextcloud / Google события; -- он не умеет создавать события; -- он не является полноценным event-aware календарем. - -Следствие: Waybar должен быть entry point, а не местом, где живет вся -календарная логика. - -## Вывод по архитектуре - -Нужна связка из двух частей: - -1. `waybar` как обзор и кнопка входа; -2. отдельное маленькое приложение/окно как рабочая поверхность. - -Рекомендованный подход: - -- hover в `waybar` показывает компактный календарный overview; -- click открывает собственный popup/tool-window; -- popup уже работает с реальными данными календаря и почты. - -## Предлагаемый UX - -### 1. Waybar popover / overview - -Минимальный состав: - -- верх: дата, `Today`, кнопка `+ Event`; -- слева: мини-месяц; -- справа или снизу: блок `Today / Tomorrow / This Week`; -- отдельный короткий блок `Unread mail`. - -Роль этого слоя: - -- быстрое чтение; -- быстрый переход; -- минимум действий; -- без тяжелой навигации. - -### 2. Tool-window / popup - -Форма окна: - -- не полноценное большое desktop app окно; -- не полноразмерный почтовый клиент; -- компактное floating window, открываемое по клику из `waybar`. - -Предпочтительная компоновка: - -- левая колонка: мини-месяц + список календарей; -- центральная зона: week view или month-agenda; -- правая колонка: `Upcoming`, `Reminders`, `Unread mail`. - -Верхняя строка: - -- `Today` -- `New event` -- `Search` -- переключение `Week / Month` - -## Мини-почта: что это значит - -Почта в этом окне должна быть не отдельным MUA, а summary layer: - -- unread messages; -- flagged / important; -- письма за сегодня; -- клик по письму открывает внешний клиент. - -Нежелательно на первом этапе: - -- полноценный composing; -- threading; -- archive/reply прямо в popup; -- попытка заменить Thunderbird или другой почтовик. - -Идея: calendar-first окно с mail summary, а не равноправный split mail/calendar -комбайн. - -## Референсы по форме и UX - -### Основной референс по форме - -`Fantastical Mini Window` - -- маленькое окно поверх рабочего контекста; -- быстрый обзор событий; -- быстрый add/search; -- ощущается как utility window, а не как полноразмерное приложение. - -Ссылка: - -- https://flexibits.com/blog/2022/04/mini-window-big-productivity-getting-the-most-from-fantastical-for-macs-mini-window/ - -### Референс по базовым календарным экранам - -`GNOME Calendar` - -- чистый month/week view; -- отдельный event editor; -- понятная структура desktop calendar без перегруза. - -Ссылка: - -- https://apps.gnome.org/Calendar/ - -### Референс по плотной рабочей компоновке - -`Notion Calendar` - -- маленький месяц + основной agenda/week layout; -- показывает, как совместить overview и рабочую область. - -Ссылка: - -- https://habr.com/ru/news/787144/ - -### Референс по идее mail+calendar продукта - -`Thunderbird` - -- полезен не как popup reference, а как пример того, что почтовый summary и - календарь могут жить рядом; -- для нашего UX слишком тяжел как direct reference. - -Ссылка: - -- https://www.thunderbird.net/en-US/ - -## Практический вывод - -Лучшее направление для реализации: - -- брать `Fantastical Mini Window` как референс формы; -- брать `GNOME Calendar` как референс календарных экранов; -- делать calendar-first popup; -- оставлять почту в формате короткого summary. - -## Следующий логический шаг - -Перед реализацией нужно решить: - -1. popup должен быть очень маленьким overview-окном или уже почти полноценным - mini-organizer; -2. mini-mail нужен только для чтения summary или уже с действиями вроде - `mark read`, `archive`, `open`. diff --git a/fedora/khal-calendar/README.md b/fedora/khal-calendar/README.md deleted file mode 100644 index 9e8de6d..0000000 --- a/fedora/khal-calendar/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# khal-calendar - -Waybar custom calendar module that prints JSON with the current time and a Pango -tooltip. Event days and upcoming events are read from `khal`. - -## Build On Bazzite - -```bash -cd ~/dotfiles/bazzite/khal-calendar -cargo build --release -install -m 755 target/release/khal-calendar ~/.config/waybar/scripts/khal-calendar -``` - -Waybar config should call the compiled binary: - -```jsonc -"exec": "~/.config/waybar/scripts/khal-calendar" -``` diff --git a/fedora/mail-counter/README.md b/fedora/mail-counter/README.md deleted file mode 100644 index 5cc118e..0000000 --- a/fedora/mail-counter/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# mail-counter - -Waybar custom mail module for Thunderbird. It reads Thunderbird's -`global-messages-db.sqlite` and prints JSON for Waybar. - -## Build On Bazzite - -```bash -cd ~/dotfiles/bazzite/mail-counter -cargo build --release -install -m 755 target/release/mail-counter ~/.config/waybar/scripts/mail -``` - -Waybar config should call the compiled binary: - -```jsonc -"exec": "~/.config/waybar/scripts/mail" -``` diff --git a/fedora/mail-counter/src/main.rs b/fedora/mail-counter/src/main.rs index e49a56d..9212672 100644 --- a/fedora/mail-counter/src/main.rs +++ b/fedora/mail-counter/src/main.rs @@ -70,7 +70,7 @@ fn unread_count(db_path: &Path) -> i64 { .unwrap_or_default() } -fn waybar_json(count: i64) -> Value { +fn mail_json(count: i64) -> Value { if count > 0 { json!({ "text": format!("{MAIL_ICON} {count}"), @@ -109,5 +109,5 @@ fn main() { return; } - println!("{}", waybar_json(unread_count(&db_path))); + println!("{}", mail_json(unread_count(&db_path))); } diff --git a/fedora/niri/config.kdl b/fedora/niri/config.kdl index 6c4ae8b..bd8f8a1 100644 --- a/fedora/niri/config.kdl +++ b/fedora/niri/config.kdl @@ -145,8 +145,8 @@ environment { } // 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" +spawn-at-startup "sh" "-c" "exec swaybg -i \"$HOME/.config/wallpaper.png\" -m fill" +spawn-at-startup "systemctl" "--user" "start" "quickshell-control-center.service" hotkey-overlay { // skip-at-startup } @@ -322,9 +322,9 @@ window-rule { } } -/-window-rule { +window-rule { match app-id="code" - // opacity 0.98 + opacity 0.8 border { // off } @@ -450,8 +450,8 @@ binds { 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+T { spawn "sh" "-c" "alacritty msg create-window -o window.opacity=0.5 || alacritty --option window.opacity=0.5"; } + Mod+Shift+T { spawn "alacritty" "--option" "window.opacity=0.5"; } // 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"; } @@ -463,14 +463,16 @@ binds { 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. + // These refresh bindings stay disabled until a local 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"; } + XF86AudioRaiseVolume allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_up"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_down"; } + XF86AudioMute allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd volume_mute"; } + XF86AudioMicMute allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd mic_mute"; } + XF86MonBrightnessUp allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd brightness_up"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "sh" "-c" "qs ipc -p \"$HOME/.config/quickshell/control-center\" call osd brightness_down"; } Mod+Q { close-window; } Mod+BackSpace { close-window; } diff --git a/fedora/packages.txt b/fedora/packages.txt new file mode 100644 index 0000000..cdf1afa --- /dev/null +++ b/fedora/packages.txt @@ -0,0 +1,21 @@ +niri +quickshell +fuzzel +alacritty +swaybg +swaylock +btop +glow +xsettingsd +pavucontrol +xsel +wl-clipboard +mpv +nautilus +khal +vdirsyncer +thunderbird +rustup +cargo +ddcutil +curl diff --git a/fedora/quickshell/control-center/Bar.qml b/fedora/quickshell/control-center/Bar.qml new file mode 100644 index 0000000..0e60afd --- /dev/null +++ b/fedora/quickshell/control-center/Bar.qml @@ -0,0 +1,517 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Quickshell +import Quickshell.Io +import Quickshell.Services.Mpris +import Quickshell.Services.Pipewire +import Quickshell.Services.SystemTray +import Quickshell.Wayland +import Quickshell.Widgets + +Item { + id: bar + + property date currentTime: new Date() + + property var controlCenter + property var settings + property var notificationCenter + property var mediaPopup + property var toggleMedia: null + property var workspaces: [] + property string windowTitle: "Desktop" + property string language: "EN" + property string weather: "N/A" + property string gpu: "GPU N/A" + property string gpuTemperature: "--" + property string mail: "" + property int cpuUsage: 0 + property int memoryUsage: 0 + property string diskUsage: "--" + property string temperature: "--" + property var audioSink: Pipewire.defaultAudioSink + property var mediaPlayer: Mpris.players.values.find(player => player.playbackState === MprisPlaybackState.Playing) + || Mpris.players.values[0] + + function start(process) { + if (!process.running) process.running = true; + } + + function focusWorkspace(index) { + Quickshell.execDetached(["niri", "msg", "action", "focus-workspace", String(index)]); + } + + function parseJson(collector, fallback) { + try { + const value = JSON.parse(collector.text); + return value === null ? fallback : value; + } catch (error) { + return fallback; + } + } + + PanelWindow { + id: barWindow + anchors { + top: true + left: true + right: true + } + implicitHeight: 40 + exclusiveZone: 40 + color: "transparent" + WlrLayershell.layer: WlrLayer.Top + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-bar" + + Rectangle { + anchors.fill: parent + anchors.topMargin: 4 + anchors.leftMargin: 4 + anchors.rightMargin: 4 + anchors.bottomMargin: 0 + radius: 14 + color: "#1e1e2e" + border.color: "#313244" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 6 + anchors.rightMargin: 6 + spacing: 6 + + RowLayout { + id: workspaceRow + spacing: 3 + + Repeater { + model: bar.workspaces + delegate: Rectangle { + required property var modelData + implicitWidth: workspaceLabel.implicitWidth + 16 + implicitHeight: 26 + radius: 10 + color: modelData.is_focused ? "#89b4fa" : (modelData.is_active ? "#45475a" : "#313244") + + Label { + id: workspaceLabel + anchors.centerIn: parent + text: modelData.name || String(modelData.idx) + color: modelData.is_focused ? "#1e1e2e" : "#cdd6f4" + font.pixelSize: 15 + font.bold: true + } + + MouseArea { + anchors.fill: parent + onClicked: bar.focusWorkspace(modelData.idx) + } + } + } + } + + Item { Layout.fillWidth: true } + + Label { + text: bar.windowTitle + color: "#cdd6f4" + font.pixelSize: 15 + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: 420 + Layout.fillWidth: true + } + + Item { Layout.fillWidth: true } + + RowLayout { + spacing: 4 + + Label { + text: bar.weather + color: "#89dceb" + font.pixelSize: 15 + ToolTip.visible: weatherMouse.containsMouse + ToolTip.text: "Weather" + MouseArea { + id: weatherMouse + anchors.fill: parent + } + } + + Label { + visible: bar.mail.length > 0 + text: bar.mail + color: "#b4befe" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "mail"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: mailMouse.containsMouse + ToolTip.text: "Unread mail" + MouseArea { + id: mailMouse + anchors.fill: parent + onClicked: Quickshell.execDetached(["thunderbird"]) + } + } + + Label { + visible: bar.mediaPlayer !== null + text: bar.mediaPlayer ? (bar.mediaPlayer.trackTitle || bar.mediaPlayer.identity) : "" + color: "#f5c2e7" + leftPadding: 19 + elide: Text.ElideRight + Layout.maximumWidth: 190 + BarIcon { name: "audio"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: mediaMouse.containsMouse + ToolTip.text: "Open media controls" + MouseArea { + id: mediaMouse + anchors.fill: parent + onClicked: { + if (bar.toggleMedia) bar.toggleMedia(); + } + } + } + + Label { + visible: !!bar.notificationCenter && bar.notificationCenter.count > 0 + text: bar.notificationCenter ? String(bar.notificationCenter.count) : "" + color: "#f38ba8" + leftPadding: 19 + BarIcon { name: "mail"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: notificationMouse.containsMouse + ToolTip.text: "Open notifications" + MouseArea { + id: notificationMouse + anchors.fill: parent + onClicked: { + if (bar.notificationCenter) bar.notificationCenter.open = !bar.notificationCenter.open; + } + } + } + + Label { + text: bar.gpu + color: "#a6e3a1" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "gpu"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: gpuMouse.containsMouse + ToolTip.text: "GPU usage" + MouseArea { + id: gpuMouse + anchors.fill: parent + } + } + + Label { + text: bar.cpuUsage + "%" + color: "#a6e3a1" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "cpu"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: cpuMouse.containsMouse + ToolTip.text: "CPU usage" + MouseArea { id: cpuMouse; anchors.fill: parent } + } + + Label { + text: bar.memoryUsage + "%" + color: "#cba6f7" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "memory"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: memoryMouse.containsMouse + ToolTip.text: "Memory usage" + MouseArea { id: memoryMouse; anchors.fill: parent } + } + + Label { + text: bar.diskUsage + color: "#f38ba8" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "disk"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: diskMouse.containsMouse + ToolTip.text: "Root filesystem" + MouseArea { id: diskMouse; anchors.fill: parent } + } + + Label { + text: bar.language + color: "#94e2d5" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "language"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: languageMouse.containsMouse + ToolTip.text: "Keyboard layout" + MouseArea { id: languageMouse; anchors.fill: parent } + } + + Label { + text: bar.audioSink && bar.audioSink.audio + ? Math.round(bar.audioSink.audio.volume * 100) + "%" + : "--" + color: "#f9e2af" + font.pixelSize: 15 + leftPadding: 19 + BarIcon { name: "audio"; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter } + ToolTip.visible: audioMouse.containsMouse + ToolTip.text: "Audio output" + MouseArea { + id: audioMouse + anchors.fill: parent + onClicked: { + if (bar.audioSink && bar.audioSink.audio) bar.audioSink.audio.muted = !bar.audioSink.audio.muted; + } + } + } + + Label { + text: Qt.formatDateTime(bar.currentTime, "dd.MM HH:mm") + color: "#cdd6f4" + font.pixelSize: 15 + ToolTip.visible: clockMouse.containsMouse + ToolTip.text: "Open calendar" + MouseArea { + id: clockMouse + anchors.fill: parent + onClicked: Quickshell.execDetached(["sh", "-c", "alacritty --title khal-popup -e bash -c 'vdirsyncer sync 2>/dev/null; ikhal'"]) + } + } + + Label { + text: "" + color: "#89b4fa" + Layout.preferredWidth: 18 + Layout.minimumWidth: 18 + Layout.maximumWidth: 18 + BarIcon { name: "gear"; size: 18; anchors.centerIn: parent } + ToolTip.visible: settingsMouse.containsMouse + ToolTip.text: "Quick settings" + MouseArea { + id: settingsMouse + anchors.fill: parent + onClicked: { + if (bar.controlCenter) bar.controlCenter.togglePanel(); + } + } + } + + Repeater { + model: SystemTray.items + delegate: Item { + required property var modelData + property bool hiddenTrayItem: !modelData + || /wayland to x11 video bridge|screen sharing|screen share/i.test(String(modelData.title || "")) + || /video-display|screen-share|screen-sharing/i.test(String(modelData.icon || "")) + visible: !hiddenTrayItem + implicitWidth: hiddenTrayItem ? 0 : 20 + implicitHeight: 22 + + Loader { + id: trayIcon + anchors.fill: parent + active: !hiddenTrayItem && modelData + sourceComponent: Component { + IconImage { + anchors.fill: parent + implicitSize: 18 + source: modelData && modelData.icon && modelData.icon.startsWith("image://") + ? modelData.icon + : (modelData ? Quickshell.iconPath(modelData.icon) : "") + } + } + } + + BarIcon { + visible: !hiddenTrayItem && !trayIcon.active + anchors.fill: parent + enabled: !hiddenTrayItem + name: "video" + size: 15 + anchors.margins: 2 + } + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: function(mouse) { + if (!modelData) return; + if (mouse.button === Qt.RightButton && modelData.hasMenu) { + modelData.display(barWindow, mouse.x, mouse.y + 20); + } else { + modelData.activate(); + } + } + } + } + } + } + } + } + } + + PwObjectTracker { + objects: [bar.audioSink] + } + + Process { + id: workspaceReader + command: ["niri", "msg", "-j", "workspaces"] + stdout: StdioCollector { + onStreamFinished: { + const value = bar.parseJson(this, []); + if (Array.isArray(value)) { + value.sort((left, right) => left.idx - right.idx); + bar.workspaces = value; + } + } + } + } + + Process { + id: windowReader + command: ["niri", "msg", "-j", "focused-window"] + stdout: StdioCollector { + onStreamFinished: { + const value = bar.parseJson(this, {}); + bar.windowTitle = value.title || "Desktop"; + } + } + } + + Process { + id: languageReader + command: ["niri", "msg", "-j", "keyboard-layouts"] + stdout: StdioCollector { + onStreamFinished: { + const value = bar.parseJson(this, {}); + const index = Number(value.current_idx); + const name = Array.isArray(value.names) && index >= 0 ? String(value.names[index] || "") : ""; + const normalized = name.toLowerCase(); + if (normalized.includes("russian") || normalized.includes("рус")) bar.language = "RU"; + else if (normalized.includes("english") || normalized.includes("англ")) bar.language = "EN"; + else if (name.length > 0) bar.language = name.slice(0, 2).toUpperCase(); + } + } + } + + Process { + id: cpuReader + command: ["sh", "-c", "awk '/^cpu / { idle=$5; total=0; for (i=2; i<=NF; i++) total += $i; print int((total-idle)*100/total) }' /proc/stat"] + stdout: StdioCollector { onStreamFinished: bar.cpuUsage = parseInt(text.trim()) || 0 } + } + + Process { + id: memoryReader + command: ["sh", "-c", "free | awk '/^Mem:/ { print int($3*100/$2) }'"] + stdout: StdioCollector { onStreamFinished: bar.memoryUsage = parseInt(text.trim()) || 0 } + } + + Process { + id: diskReader + command: ["sh", "-c", "df -P / | awk 'NR==2 { print $5 }'"] + stdout: StdioCollector { onStreamFinished: bar.diskUsage = text.trim() || "--" } + } + + Process { + id: temperatureReader + command: ["sh", "-c", "max=0; for file in /sys/class/thermal/thermal_zone*/temp; do value=$(cat $file 2>/dev/null); [ $value -gt $max ] 2>/dev/null && max=$value; done; if [ $max -gt 0 ]; then echo $((max / 1000))C; else echo --; fi"] + stdout: StdioCollector { onStreamFinished: bar.temperature = text.trim() || "--" } + } + + Process { + id: gpuReader + command: ["sh", "-c", "nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null | head -1"] + stdout: StdioCollector { + onStreamFinished: { + const parts = text.trim().split(","); + const usage = parseInt((parts[0] || "").trim()); + const temperature = parseInt((parts[1] || "").trim()); + bar.gpu = isNaN(usage) ? "N/A" : usage + "%"; + bar.gpuTemperature = isNaN(temperature) ? "--" : temperature + "C"; + } + } + } + + Process { + id: weatherReader + command: ["bash", Quickshell.shellPath("../scripts/weather.sh")] + stdout: StdioCollector { + onStreamFinished: { + const value = bar.parseJson(this, {}); + bar.weather = value.text || "N/A"; + } + } + } + + Process { + id: mailReader + command: ["sh", "-c", "if [ -x $HOME/.local/bin/mail-counter ]; then $HOME/.local/bin/mail-counter; else printf '{}'; fi"] + stdout: StdioCollector { + onStreamFinished: { + const value = bar.parseJson(this, {}); + bar.mail = value.text || ""; + } + } + } + + Timer { + id: refreshTimer + interval: bar.settings ? bar.settings.temperatureInterval : 2000 + running: true + repeat: true + onTriggered: { + bar.currentTime = new Date(); + bar.start(windowReader); + bar.start(cpuReader); + bar.start(memoryReader); + bar.start(diskReader); + bar.start(temperatureReader); + bar.start(gpuReader); + bar.start(mailReader); + } + } + + Timer { + id: weatherTimer + interval: 900000 + running: true + repeat: true + onTriggered: bar.start(weatherReader) + } + + Timer { + id: languageTimer + interval: 200 + running: true + repeat: true + onTriggered: bar.start(languageReader) + } + + Timer { + id: workspaceTimer + interval: 100 + running: true + repeat: true + onTriggered: bar.start(workspaceReader) + } + + Component.onCompleted: { + bar.start(workspaceReader); + bar.start(windowReader); + bar.start(languageReader); + bar.start(cpuReader); + bar.start(memoryReader); + bar.start(diskReader); + bar.start(temperatureReader); + bar.start(gpuReader); + bar.start(weatherReader); + bar.start(mailReader); + } +} diff --git a/fedora/quickshell/control-center/BarIcon.qml b/fedora/quickshell/control-center/BarIcon.qml new file mode 100644 index 0000000..8721409 --- /dev/null +++ b/fedora/quickshell/control-center/BarIcon.qml @@ -0,0 +1,16 @@ +import QtQuick + +Image { + id: root + + property string name + property real size: 15 + + width: size + height: size + source: Qt.resolvedUrl("icons/" + name + ".svg") + sourceSize.width: size * 2 + sourceSize.height: size * 2 + fillMode: Image.PreserveAspectFit + smooth: true +} diff --git a/fedora/quickshell/control-center/MediaPopup.qml b/fedora/quickshell/control-center/MediaPopup.qml new file mode 100644 index 0000000..fec45ca --- /dev/null +++ b/fedora/quickshell/control-center/MediaPopup.qml @@ -0,0 +1,209 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Quickshell +import Quickshell.Services.Mpris +import Quickshell.Wayland + +Item { + id: root + + property bool open: false + property var selectedPlayer: null + property var player: selectedPlayer + || Mpris.players.values.find(candidate => candidate.playbackState === MprisPlaybackState.Playing) + || Mpris.players.values[0] + || null + + signal dismissed() + + function formatTime(value) { + if (!value || value < 0) return "0:00"; + const seconds = Math.floor(value); + return Math.floor(seconds / 60) + ":" + String(seconds % 60).padStart(2, "0"); + } + + PanelWindow { + visible: root.open + color: "transparent" + anchors { + top: true + bottom: true + left: true + right: true + } + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-media-popup" + + MouseArea { + anchors.fill: parent + onClicked: root.dismissed() + } + + Rectangle { + id: card + width: Math.min(410, parent.width - 32) + height: root.player ? 330 : 150 + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 52 + radius: 20 + color: "#f5f2ea" + border.color: "#d8d0c2" + border.width: 1 + z: 1 + + MouseArea { + anchors.fill: parent + onClicked: function(mouse) { mouse.accepted = true; } + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 10 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Media" + color: "#252321" + font.pixelSize: 20 + font.bold: true + Layout.fillWidth: true + } + Label { + text: root.player ? root.player.identity : "No player" + color: "#7c756c" + elide: Text.ElideRight + } + Rectangle { + width: 26 + height: 26 + radius: 13 + color: "#e5e0d7" + Label { + anchors.centerIn: parent + text: "x" + color: "#6e675f" + } + MouseArea { + anchors.fill: parent + onClicked: root.dismissed() + } + } + } + + RowLayout { + visible: root.player !== null + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 14 + + Rectangle { + Layout.preferredWidth: 132 + Layout.preferredHeight: 132 + radius: 14 + color: "#e5e0d7" + clip: true + + Image { + id: cover + anchors.fill: parent + source: root.player ? root.player.trackArtUrl : "" + fillMode: Image.PreserveAspectCrop + asynchronous: true + } + Label { + anchors.centerIn: parent + visible: cover.status !== Image.Ready + text: "♪" + color: "#8b8176" + font.pixelSize: 42 + } + } + + ColumnLayout { + Layout.fillWidth: true + spacing: 4 + + Label { + text: root.player ? (root.player.trackTitle || "Unknown track") : "" + color: "#252321" + font.pixelSize: 17 + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + Label { + text: root.player ? (root.player.trackArtist || root.player.trackAlbum || "Unknown artist") : "" + color: "#7c756c" + elide: Text.ElideRight + Layout.fillWidth: true + } + Item { Layout.fillHeight: true } + Label { + text: root.player ? root.formatTime(root.player.position) + " / " + root.formatTime(root.player.length) : "" + color: "#7c756c" + font.pixelSize: 11 + } + } + } + + Slider { + visible: root.player && root.player.length > 0 + Layout.fillWidth: true + from: 0 + to: root.player ? root.player.length : 1 + value: root.player ? root.player.position : 0 + onMoved: { + if (root.player && root.player.canSeek) root.player.position = value; + } + } + + RowLayout { + visible: root.player !== null + Layout.alignment: Qt.AlignHCenter + spacing: 14 + + Button { + text: "Prev" + enabled: !!(root.player && root.player.canGoPrevious) + onClicked: root.player.previous() + } + Button { + text: root.player && root.player.playbackState === MprisPlaybackState.Playing ? "Pause" : "Play" + enabled: !!(root.player && root.player.canTogglePlaying) + onClicked: root.player.togglePlaying() + } + Button { + text: "Next" + enabled: !!(root.player && root.player.canGoNext) + onClicked: root.player.next() + } + } + + RowLayout { + visible: Mpris.players.values.length > 1 + Layout.fillWidth: true + Label { + text: "Players" + color: "#7c756c" + Layout.fillWidth: true + } + Repeater { + model: Mpris.players + delegate: Button { + required property var modelData + text: modelData.identity + onClicked: root.selectedPlayer = modelData + } + } + } + } + } + } +} diff --git a/fedora/quickshell/control-center/Notifications.qml b/fedora/quickshell/control-center/Notifications.qml new file mode 100644 index 0000000..116da32 --- /dev/null +++ b/fedora/quickshell/control-center/Notifications.qml @@ -0,0 +1,220 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Quickshell +import Quickshell.Services.Notifications +import Quickshell.Wayland + +Item { + id: root + + property bool open: false + property bool dnd: false + property bool toastOpen: false + property var latest: null + readonly property int count: server.trackedNotifications ? server.trackedNotifications.values.length : 0 + + signal dismissed() + + NotificationServer { + id: server + keepOnReload: true + onNotification: function(notification) { + notification.tracked = true; + root.latest = notification; + if (!root.dnd) { + root.toastOpen = true; + toastTimer.restart(); + } + } + } + + Timer { + id: toastTimer + interval: 5000 + repeat: false + onTriggered: root.toastOpen = false + } + + PanelWindow { + visible: root.toastOpen && !root.open && root.latest !== null + color: "transparent" + anchors { top: true; bottom: true; left: true; right: true } + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-notification-toast" + + Rectangle { + width: Math.min(390, parent.width - 32) + height: 100 + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: 16 + radius: 16 + color: "#f5f2ea" + border.color: "#d8d0c2" + border.width: 1 + + MouseArea { + anchors.fill: parent + onClicked: { + root.toastOpen = false; + root.open = true; + } + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 14 + spacing: 3 + Label { + text: root.latest ? root.latest.appName : "" + color: "#7c756c" + font.pixelSize: 11 + Layout.fillWidth: true + elide: Text.ElideRight + } + Label { + text: root.latest ? root.latest.summary : "" + color: "#252321" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + elide: Text.ElideRight + } + Label { + text: root.latest ? root.latest.body : "" + color: "#5f5952" + Layout.fillWidth: true + elide: Text.ElideRight + } + } + } + } + + PanelWindow { + visible: root.open + color: "transparent" + anchors { top: true; bottom: true; left: true; right: true } + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-notification-center" + + MouseArea { + anchors.fill: parent + onClicked: root.dismissed() + } + + Rectangle { + width: Math.min(430, parent.width - 32) + height: Math.min(parent.height - 32, 700) + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: 16 + radius: 20 + color: "#f5f2ea" + border.color: "#d8d0c2" + border.width: 1 + z: 1 + + MouseArea { + anchors.fill: parent + onClicked: function(mouse) { mouse.accepted = true } + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: 18 + spacing: 10 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Notifications" + color: "#252321" + font.pixelSize: 22 + font.bold: true + Layout.fillWidth: true + } + Button { + text: root.dnd ? "DND on" : "DND off" + onClicked: root.dnd = !root.dnd + } + Button { + text: "Close" + onClicked: root.dismissed() + } + } + + Label { + visible: root.count === 0 + text: "No notifications" + color: "#7c756c" + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 18 + } + + ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + ColumnLayout { + width: parent.width + spacing: 8 + + Repeater { + model: server.trackedNotifications + delegate: Rectangle { + required property var modelData + Layout.fillWidth: true + implicitHeight: notificationColumn.implicitHeight + 22 + radius: 14 + color: "#e8e3da" + + ColumnLayout { + id: notificationColumn + anchors.fill: parent + anchors.margins: 11 + spacing: 3 + + RowLayout { + Layout.fillWidth: true + Label { + text: modelData.appName + color: "#7c756c" + font.pixelSize: 11 + Layout.fillWidth: true + elide: Text.ElideRight + } + Button { + text: "x" + onClicked: modelData.dismiss() + } + } + Label { + text: modelData.summary + color: "#252321" + font.pixelSize: 15 + font.bold: true + Layout.fillWidth: true + wrapMode: Text.Wrap + } + Label { + text: modelData.body + color: "#5f5952" + Layout.fillWidth: true + wrapMode: Text.Wrap + } + } + } + } + } + } + } + } + } +} diff --git a/fedora/quickshell/control-center/Osd.qml b/fedora/quickshell/control-center/Osd.qml new file mode 100644 index 0000000..ec604a0 --- /dev/null +++ b/fedora/quickshell/control-center/Osd.qml @@ -0,0 +1,76 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Quickshell +import Quickshell.Wayland + +Item { + id: root + + property bool open: false + property string kind: "volume" + property real value: 0 + property bool muted: false + + PanelWindow { + visible: root.open + color: "transparent" + anchors { + top: true + bottom: true + left: true + right: true + } + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-osd" + + Rectangle { + width: 300 + height: 78 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 110 + radius: 20 + color: "#1e1e2e" + border.color: "#45475a" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 12 + + Label { + text: root.kind === "brightness" ? "Display" : (root.muted ? "Muted" : "Volume") + color: "#cdd6f4" + font.pixelSize: 14 + font.bold: true + } + + Rectangle { + Layout.fillWidth: true + height: 8 + radius: 4 + color: "#313244" + + Rectangle { + width: parent.width * Math.max(0, Math.min(1, root.value)) + height: parent.height + radius: 4 + color: root.kind === "brightness" ? "#f9e2af" : "#89b4fa" + } + } + + Label { + text: Math.round(root.value * 100) + "%" + color: "#cdd6f4" + font.pixelSize: 15 + font.bold: true + } + } + } + } +} diff --git a/fedora/quickshell/control-center/Settings.qml b/fedora/quickshell/control-center/Settings.qml new file mode 100644 index 0000000..3d48b27 --- /dev/null +++ b/fedora/quickshell/control-center/Settings.qml @@ -0,0 +1,36 @@ +import QtQuick + +import Quickshell +import Quickshell.Io + +QtObject { + id: root + + property alias temperatureInterval: values.temperatureInterval + property alias temperatureWarning: values.temperatureWarning + property alias temperatureCritical: values.temperatureCritical + + function setTemperatureWarning(value) { + root.temperatureWarning = Math.min(value, root.temperatureCritical - 1); + } + + function setTemperatureCritical(value) { + root.temperatureCritical = Math.max(value, root.temperatureWarning + 1); + } + + property FileView settingsFile: FileView { + path: Quickshell.statePath("control-center.json") + printErrors: false + watchChanges: true + onFileChanged: reload() + onAdapterUpdated: writeAdapter() + + JsonAdapter { + id: values + + property int temperatureInterval: 2000 + property int temperatureWarning: 75 + property int temperatureCritical: 90 + } + } +} diff --git a/fedora/quickshell/control-center/icons/audio.svg b/fedora/quickshell/control-center/icons/audio.svg new file mode 100644 index 0000000..3aa4499 --- /dev/null +++ b/fedora/quickshell/control-center/icons/audio.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/cpu.svg b/fedora/quickshell/control-center/icons/cpu.svg new file mode 100644 index 0000000..3fe9edd --- /dev/null +++ b/fedora/quickshell/control-center/icons/cpu.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/disk.svg b/fedora/quickshell/control-center/icons/disk.svg new file mode 100644 index 0000000..a4da919 --- /dev/null +++ b/fedora/quickshell/control-center/icons/disk.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/gear.svg b/fedora/quickshell/control-center/icons/gear.svg new file mode 100644 index 0000000..618437f --- /dev/null +++ b/fedora/quickshell/control-center/icons/gear.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/gpu.svg b/fedora/quickshell/control-center/icons/gpu.svg new file mode 100644 index 0000000..2bc8f49 --- /dev/null +++ b/fedora/quickshell/control-center/icons/gpu.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/language.svg b/fedora/quickshell/control-center/icons/language.svg new file mode 100644 index 0000000..9586457 --- /dev/null +++ b/fedora/quickshell/control-center/icons/language.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/mail.svg b/fedora/quickshell/control-center/icons/mail.svg new file mode 100644 index 0000000..61da969 --- /dev/null +++ b/fedora/quickshell/control-center/icons/mail.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/memory.svg b/fedora/quickshell/control-center/icons/memory.svg new file mode 100644 index 0000000..7e4bc5b --- /dev/null +++ b/fedora/quickshell/control-center/icons/memory.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/temperature.svg b/fedora/quickshell/control-center/icons/temperature.svg new file mode 100644 index 0000000..567c74f --- /dev/null +++ b/fedora/quickshell/control-center/icons/temperature.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/icons/video.svg b/fedora/quickshell/control-center/icons/video.svg new file mode 100644 index 0000000..756776c --- /dev/null +++ b/fedora/quickshell/control-center/icons/video.svg @@ -0,0 +1 @@ + diff --git a/fedora/quickshell/control-center/shell.qml b/fedora/quickshell/control-center/shell.qml new file mode 100644 index 0000000..0392c44 --- /dev/null +++ b/fedora/quickshell/control-center/shell.qml @@ -0,0 +1,748 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Quickshell +import Quickshell.Bluetooth +import Quickshell.Io +import Quickshell.Networking +import Quickshell.Services.Pipewire +import Quickshell.Services.UPower +import Quickshell.Wayland + +Scope { + id: root + + property bool open: false + property bool panelVisible: false + property bool mediaOpen: false + property bool notificationsOpen: false + property bool osdOpen: false + property string osdKind: "volume" + property int brightness: 0 + property var pendingNetwork: null + property string wifiPassword: "" + property var wifiDevice: Networking.devices.values.find(device => device.type === DeviceType.Wifi) + property var bluetoothAdapter: Bluetooth.defaultAdapter + property var audioSink: Pipewire.defaultAudioSink + property var settings: statusSettings + property alias cpuTemperature: statusBar.temperature + property alias gpuTemperature: statusBar.gpuTemperature + + Settings { + id: statusSettings + } + + Bar { + id: statusBar + controlCenter: root + settings: root.settings + mediaPopup: mediaPopup + toggleMedia: function() { root.mediaOpen = !root.mediaOpen } + notificationCenter: notificationCenter + } + + MediaPopup { + id: mediaPopup + open: root.mediaOpen + onDismissed: root.mediaOpen = false + } + + Notifications { + id: notificationCenter + open: root.notificationsOpen + onDismissed: root.notificationsOpen = false + } + + Osd { + open: root.osdOpen + kind: root.osdKind + value: root.osdKind === "brightness" + ? root.brightness / 100 + : (root.audioSink && root.audioSink.audio ? root.audioSink.audio.volume : 0) + muted: root.audioSink && root.audioSink.audio ? root.audioSink.audio.muted : false + } + + function setBrightness(value) { + const level = Math.max(0, Math.min(100, Math.round(value))); + Quickshell.execDetached(["ddcutil", "setvcp", "10", String(level)]); + root.brightness = level; + } + + function connectWifi(network) { + if (network.security === WifiSecurityType.Open) { + network.connect(); + return; + } + + root.pendingNetwork = network; + root.wifiPassword = ""; + } + + function submitWifiPassword() { + if (root.pendingNetwork && root.wifiPassword.length > 0) { + root.pendingNetwork.connectWithPsk(root.wifiPassword); + root.pendingNetwork = null; + root.wifiPassword = ""; + } + } + + function showOsd(kind) { + root.osdKind = kind; + root.osdOpen = true; + osdTimer.restart(); + } + + function adjustBrightness(delta) { + const current = root.brightness > 0 ? root.brightness : 50; + root.setBrightness(current + delta); + root.showOsd("brightness"); + } + + function temperatureColor(value) { + const match = String(value).match(/(\d+)C\s*$/); + const temperature = match ? Number(match[1]) : -1; + if (temperature < 0) return "#806d95"; + if (temperature >= root.settings.temperatureCritical) return "#c94f6d"; + if (temperature >= root.settings.temperatureWarning) return "#996315"; + return "#4d7c38"; + } + + function openPanel() { + closePanelTimer.stop(); + root.panelVisible = true; + openPanelTimer.restart(); + } + + function closePanel() { + openPanelTimer.stop(); + root.open = false; + closePanelTimer.restart(); + } + + function togglePanel() { + if (root.open || root.panelVisible) root.closePanel(); + else root.openPanel(); + } + + Timer { + id: openPanelTimer + interval: 1 + repeat: false + onTriggered: root.open = true + } + + Timer { + id: closePanelTimer + interval: 240 + repeat: false + onTriggered: root.panelVisible = false + } + + IpcHandler { + target: "controlcenter" + + function toggle() { + root.togglePanel(); + } + + function open() { + root.openPanel(); + } + + function close() { + root.closePanel(); + } + } + + IpcHandler { + target: "osd" + + function volume_up() { + Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+"]); + root.showOsd("volume"); + } + + function volume_down() { + Quickshell.execDetached(["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]); + root.showOsd("volume"); + } + + function volume_mute() { + Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle"]); + root.showOsd("volume"); + } + + function mic_mute() { + Quickshell.execDetached(["wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"]); + root.showOsd("mic"); + } + + function brightness_up() { + root.adjustBrightness(5); + } + + function brightness_down() { + root.adjustBrightness(-5); + } + } + + Timer { + id: osdTimer + interval: 1400 + repeat: false + onTriggered: root.osdOpen = false + } + + PwObjectTracker { + objects: [root.audioSink] + } + + Process { + id: brightnessReader + command: ["sh", "-c", "ddcutil getvcp 10 2>/dev/null | sed -n 's/.*current value = *\\([0-9]*\\).*/\\1/p'"] + stdout: StdioCollector { + onStreamFinished: { + const value = parseInt(text.trim()); + if (!isNaN(value)) root.brightness = value; + } + } + } + + Timer { + id: brightnessPoll + interval: 3000 + repeat: true + running: root.open + onTriggered: { + if (!brightnessReader.running) brightnessReader.running = true; + } + } + + PanelWindow { + visible: root.panelVisible + color: "transparent" + anchors { + top: true + bottom: true + left: true + right: true + } + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.keyboardFocus: root.panelVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None + WlrLayershell.namespace: "quickshell-control-center" + + MouseArea { + anchors.fill: parent + onClicked: root.closePanel() + } + + Rectangle { + id: card + width: Math.min(470, parent.width - 32) + height: parent.height + anchors.top: parent.top + anchors.topMargin: 0 + x: root.open ? parent.width - width - 16 : parent.width + 24 + radius: 20 + color: "#f5f2ea" + border.color: "#d8d0c2" + border.width: 1 + z: 1 + + Behavior on x { + NumberAnimation { + duration: 220 + easing.type: Easing.OutCubic + } + } + + MouseArea { + anchors.fill: parent + onClicked: mouse.accepted = true + } + + ColumnLayout { + id: content + anchors.fill: parent + anchors.margins: 18 + spacing: 12 + + RowLayout { + Layout.fillWidth: true + + ColumnLayout { + Layout.fillWidth: true + spacing: 0 + + Label { + text: "Control center" + color: "#252321" + font.pixelSize: 22 + font.bold: true + } + Label { + text: "Niri / QuickShell" + color: "#7c756c" + font.pixelSize: 12 + } + } + + Button { + text: "✕" + ToolTip.visible: hovered + ToolTip.text: "Close" + onClicked: root.closePanel() + } + } + + ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + ColumnLayout { + width: parent.width + spacing: 10 + + Rectangle { + Layout.fillWidth: true + implicitHeight: wifiColumn.implicitHeight + 24 + radius: 14 + color: "#e5f0ef" + + ColumnLayout { + id: wifiColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Wi-Fi" + color: "#1c666d" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Label { + text: root.wifiDevice ? (root.wifiDevice.name || "Available") : "Unavailable" + color: "#52777a" + elide: Text.ElideRight + } + Switch { + checked: Networking.wifiEnabled + enabled: Networking.wifiHardwareEnabled + onToggled: Networking.wifiEnabled = checked + } + } + + RowLayout { + visible: root.wifiDevice !== null + Layout.fillWidth: true + Label { + text: root.wifiDevice && root.wifiDevice.networks.values.find(network => network.connected) + ? root.wifiDevice.networks.values.find(network => network.connected).name + : "Not connected" + color: "#252321" + elide: Text.ElideRight + Layout.fillWidth: true + } + Button { + text: "Scan" + onClicked: { + if (root.wifiDevice) root.wifiDevice.scannerEnabled = true; + } + } + } + + Repeater { + model: root.wifiDevice ? root.wifiDevice.networks : null + delegate: RowLayout { + Layout.fillWidth: true + spacing: 8 + + Label { + text: modelData.name + color: "#252321" + elide: Text.ElideRight + Layout.fillWidth: true + } + Label { + text: modelData.connected ? "Connected" : Math.round(modelData.signalStrength) + "%" + color: modelData.connected ? "#1c666d" : "#7c756c" + } + Button { + text: modelData.connected ? "Disconnect" : "Connect" + enabled: !modelData.stateChanging + onClicked: modelData.connected ? modelData.disconnect() : root.connectWifi(modelData) + } + } + } + + RowLayout { + visible: root.pendingNetwork !== null + Layout.fillWidth: true + TextField { + Layout.fillWidth: true + placeholderText: "Password for " + (root.pendingNetwork ? root.pendingNetwork.name : "network") + echoMode: TextInput.Password + text: root.wifiPassword + onTextChanged: root.wifiPassword = text + onAccepted: root.submitWifiPassword() + } + Button { + text: "Join" + enabled: root.wifiPassword.length > 0 + onClicked: root.submitWifiPassword() + } + } + } + } + + Rectangle { + Layout.fillWidth: true + implicitHeight: bluetoothColumn.implicitHeight + 24 + radius: 14 + color: "#eceafd" + + ColumnLayout { + id: bluetoothColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Bluetooth" + color: "#55499c" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Switch { + checked: root.bluetoothAdapter ? root.bluetoothAdapter.enabled : false + enabled: root.bluetoothAdapter !== null + onToggled: { + if (root.bluetoothAdapter) root.bluetoothAdapter.enabled = checked; + } + } + Button { + text: root.bluetoothAdapter && root.bluetoothAdapter.discovering ? "Stop scan" : "Scan" + enabled: root.bluetoothAdapter && root.bluetoothAdapter.enabled + onClicked: { + if (root.bluetoothAdapter) root.bluetoothAdapter.discovering = !root.bluetoothAdapter.discovering; + } + } + } + + Repeater { + model: root.bluetoothAdapter ? root.bluetoothAdapter.devices : null + delegate: RowLayout { + Layout.fillWidth: true + spacing: 8 + + ColumnLayout { + Layout.fillWidth: true + spacing: 0 + Label { + text: modelData.name || modelData.deviceName || "Unknown device" + color: "#252321" + elide: Text.ElideRight + Layout.fillWidth: true + } + Label { + text: modelData.connected ? "Connected" : (modelData.paired ? "Paired" : "Not paired") + color: "#7c756c" + font.pixelSize: 11 + } + } + Label { + visible: modelData.batteryAvailable + text: Math.round(modelData.battery * 100) + "%" + color: "#7c756c" + } + Button { + text: modelData.connected ? "Disconnect" : (modelData.paired ? "Connect" : "Pair") + onClicked: { + if (modelData.connected) modelData.disconnect(); + else if (modelData.paired) modelData.connect(); + else modelData.pair(); + } + } + } + } + } + } + + Rectangle { + Layout.fillWidth: true + implicitHeight: audioColumn.implicitHeight + 24 + radius: 14 + color: "#fff1d7" + + ColumnLayout { + id: audioColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Audio" + color: "#996315" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Label { + text: root.audioSink ? (root.audioSink.description || "Default output") : "Unavailable" + color: "#806a48" + elide: Text.ElideRight + Layout.maximumWidth: 230 + } + } + + RowLayout { + Layout.fillWidth: true + Button { + text: root.audioSink && root.audioSink.audio && root.audioSink.audio.muted ? "Unmute" : "Mute" + enabled: root.audioSink && root.audioSink.audio + onClicked: { + if (root.audioSink && root.audioSink.audio) root.audioSink.audio.muted = !root.audioSink.audio.muted; + } + } + Slider { + Layout.fillWidth: true + from: 0 + to: 1 + value: root.audioSink && root.audioSink.audio ? root.audioSink.audio.volume : 0 + enabled: root.audioSink && root.audioSink.audio + onMoved: { + if (root.audioSink && root.audioSink.audio) root.audioSink.audio.volume = value; + } + } + Label { + text: root.audioSink && root.audioSink.audio ? Math.round(root.audioSink.audio.volume * 100) + "%" : "--" + color: "#806a48" + } + } + + Repeater { + model: Pipewire.nodes + delegate: RowLayout { + visible: modelData.isSink && !modelData.isStream + Layout.fillWidth: true + Label { + text: modelData.description || modelData.name + color: "#252321" + elide: Text.ElideRight + Layout.fillWidth: true + } + Button { + text: modelData === root.audioSink ? "Default" : "Use" + enabled: modelData !== root.audioSink + onClicked: Pipewire.preferredDefaultAudioSink = modelData + } + } + } + } + } + + Rectangle { + Layout.fillWidth: true + implicitHeight: displayColumn.implicitHeight + 24 + radius: 14 + color: "#f8e4dc" + + ColumnLayout { + id: displayColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Display brightness" + color: "#9e4d39" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Label { + text: root.brightness > 0 ? root.brightness + "%" : "Unavailable" + color: "#8b665b" + } + } + Slider { + Layout.fillWidth: true + from: 1 + to: 100 + value: root.brightness + enabled: root.brightness > 0 + onPressedChanged: { + if (!pressed) root.setBrightness(value); + } + } + } + } + + Rectangle { + Layout.fillWidth: true + implicitHeight: statusColumn.implicitHeight + 24 + radius: 14 + color: "#eee8f7" + + ColumnLayout { + id: statusColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Status bar" + color: "#684b8f" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Label { + text: "Temperature" + color: "#806d95" + } + } + + RowLayout { + Layout.fillWidth: true + Label { + text: "CPU temperature" + color: "#252321" + Layout.fillWidth: true + } + Label { + text: root.cpuTemperature + color: root.temperatureColor(root.cpuTemperature) + } + } + + RowLayout { + Layout.fillWidth: true + Label { + text: "GPU temperature" + color: "#252321" + Layout.fillWidth: true + } + Label { + text: root.gpuTemperature + color: root.temperatureColor(root.gpuTemperature) + } + } + + RowLayout { + Layout.fillWidth: true + Label { + text: "Refresh interval" + color: "#252321" + Layout.fillWidth: true + } + ComboBox { + model: ["1 second", "2 seconds", "5 seconds"] + currentIndex: [1000, 2000, 5000].indexOf(root.settings.temperatureInterval) + onActivated: root.settings.temperatureInterval = [1000, 2000, 5000][currentIndex] + } + } + + RowLayout { + Layout.fillWidth: true + Label { + text: "Warning / critical" + color: "#252321" + Layout.fillWidth: true + } + SpinBox { + from: 40 + to: 99 + value: root.settings.temperatureWarning + editable: true + onValueModified: root.settings.setTemperatureWarning(value) + } + Label { + text: "/" + color: "#7c756c" + } + SpinBox { + from: 41 + to: 110 + value: root.settings.temperatureCritical + editable: true + onValueModified: root.settings.setTemperatureCritical(value) + } + Label { + text: "°C" + color: "#7c756c" + } + } + } + } + + Rectangle { + Layout.fillWidth: true + implicitHeight: powerColumn.implicitHeight + 24 + radius: 14 + color: "#e8f1df" + + ColumnLayout { + id: powerColumn + anchors.fill: parent + anchors.margins: 12 + spacing: 8 + + RowLayout { + Layout.fillWidth: true + Label { + text: "Power profile" + color: "#4d7c38" + font.pixelSize: 16 + font.bold: true + Layout.fillWidth: true + } + Label { + text: PowerProfile.toString(PowerProfiles.profile) + color: "#66825a" + } + } + + RowLayout { + Layout.fillWidth: true + Button { + text: "Saver" + Layout.fillWidth: true + onClicked: PowerProfiles.profile = PowerProfile.PowerSaver + } + Button { + text: "Balanced" + Layout.fillWidth: true + onClicked: PowerProfiles.profile = PowerProfile.Balanced + } + Button { + text: "Performance" + enabled: PowerProfiles.hasPerformanceProfile + Layout.fillWidth: true + onClicked: PowerProfiles.profile = PowerProfile.Performance + } + } + } + } + } + } + } + } + } +} diff --git a/fedora/quickshell/scripts/gpu.sh b/fedora/quickshell/scripts/gpu.sh new file mode 100644 index 0000000..eceb28e --- /dev/null +++ b/fedora/quickshell/scripts/gpu.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null) +if [ -z "$data" ]; then + printf '%s\n' '{"text":"N/A"}' + exit 0 +fi + +usage=$(printf '%s\n' "$data" | cut -d',' -f1 | tr -d ' ') +temp=$(printf '%s\n' "$data" | cut -d',' -f2 | tr -d ' ') +printf '{"text":"%s%% %sC"}\n' "$usage" "$temp" diff --git a/fedora/quickshell/scripts/weather.sh b/fedora/quickshell/scripts/weather.sh new file mode 100644 index 0000000..e9d56ea --- /dev/null +++ b/fedora/quickshell/scripts/weather.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +weather=$(curl -4 -sS --connect-timeout 3 --max-time 8 "https://wttr.in/?format=%c%t" 2>/dev/null) +if [ -z "$weather" ] || printf '%s' "$weather" | grep -q "Unknown"; then + printf '%s\n' '{"text":"N/A"}' + exit 0 +fi + +printf '{"text":"%s"}\n' "$weather" diff --git a/fedora/systemd/user/quickshell-control-center.service b/fedora/systemd/user/quickshell-control-center.service new file mode 100644 index 0000000..10ea9eb --- /dev/null +++ b/fedora/systemd/user/quickshell-control-center.service @@ -0,0 +1,10 @@ +[Unit] +Description=QuickShell control center +PartOf=niri.service +After=niri.service + +[Service] +ExecStart=/usr/bin/qs -p %h/.config/quickshell/control-center +Restart=always +RestartSec=2 +Environment=QT_QPA_PLATFORM=wayland diff --git a/fedora/wallpapers/raspberry.png b/fedora/wallpapers/raspberry.png deleted file mode 100644 index cf7b725..0000000 Binary files a/fedora/wallpapers/raspberry.png and /dev/null differ diff --git a/bazzite/wallpapers/raspberry.png b/fedora/wallpapers/wallpaper.png similarity index 100% rename from bazzite/wallpapers/raspberry.png rename to fedora/wallpapers/wallpaper.png diff --git a/fedora/waybar/config.jsonc b/fedora/waybar/config.jsonc deleted file mode 100644 index 1d309af..0000000 --- a/fedora/waybar/config.jsonc +++ /dev/null @@ -1,179 +0,0 @@ -// -*- mode: jsonc -*- -{ - "layer": "top", - "height": 32, - "spacing": 8, - - "modules-left": [ - "niri/workspaces" - ], - "modules-center": [ - "niri/window" - ], - "modules-right": [ - "privacy", - "custom/mail", - "custom/weather", - "pulseaudio", - "network", - "niri/language", - "power-profiles-daemon", - "cpu", - "memory", - "temperature", - "custom/gpu", - "disk", - "custom/calendar", - "tray" - ], - - "niri/workspaces": { - "format": "{index}" - }, - - "niri/window": { - "format": "{}", - "max-length": 50, - "align": 0.5, - "justify": "center" - }, - - "niri/language": { - "format": "{short}", - "align": 0.5, - "justify": "center" - }, - - "privacy": { - "icon-spacing": 4, - "icon-size": 16, - "transition-duration": 250, - "modules": [ - { "type": "screenshare" }, - { "type": "audio-in" }, - { "type": "audio-out" } - ] - }, - - "custom/mail": { - "format": "{}", - "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": " {percentage_used}%", - "path": "/", - "tooltip-format": "{used} / {total} ({percentage_used}%)", - "align": 0.5, - "justify": "center" - }, - - "tray": { - "spacing": 10 - }, - - "custom/calendar": { - "format": " {}", - "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, - "align": 0.5, - "justify": "center" - }, - - "memory": { - "format": " {}%", - "align": 0.5, - "justify": "center" - }, - - "temperature": { - "critical-threshold": 80, - "format": " {temperatureC}°C", - "align": 0.5, - "justify": "center" - }, - - "network": { - "format-wifi": "{icon}", - "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": "", - "align": 0.5, - "justify": "center" - }, - - "pulseaudio": { - "format": "{icon} {volume}% {format_source}", - "format-bluetooth": "{icon} {volume}% {format_source}", - "format-bluetooth-muted": " {format_source}", - "format-muted": " {format_source}", - "format-source": "{volume}%", - "format-source-muted": "", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click": "pavucontrol", - "align": 0.5, - "justify": "center" - }, - - "power-profiles-daemon": { - "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", - "tooltip": true, - "align": 0.5, - "justify": "center", - "format-icons": { - "default": "", - "performance": "", - "balanced": "", - "power-saver": "" - } - } -} diff --git a/fedora/waybar/scripts/gpu.sh b/fedora/waybar/scripts/gpu.sh deleted file mode 100755 index fb870d1..0000000 --- a/fedora/waybar/scripts/gpu.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -data=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null) -if [ -z "$data" ]; then - echo '{"text": "GPU N/A", "tooltip": "nvidia-smi not available"}' - exit 0 -fi -usage=$(echo "$data" | cut -d',' -f1 | tr -d ' ') -temp=$(echo "$data" | cut -d',' -f2 | tr -d ' ') -echo "{\"text\": \"GPU ${usage}% ${temp}°C\", \"tooltip\": \"GPU: ${usage}%\\nTemp: ${temp}°C\", \"class\": \"\"}" diff --git a/fedora/waybar/scripts/weather.sh b/fedora/waybar/scripts/weather.sh deleted file mode 100755 index e37ecd7..0000000 --- a/fedora/waybar/scripts/weather.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -weather=$(curl -s "wttr.in/?format=%c%t" 2>/dev/null) -if [ -z "$weather" ] || echo "$weather" | grep -q "Unknown"; then - echo '{"text": "N/A", "tooltip": "Weather unavailable"}' - exit 0 -fi -tooltip=$(curl -s "wttr.in/?format=%l:+%C+%t+%w+%h" 2>/dev/null) -echo "{\"text\": \"${weather}\", \"tooltip\": \"${tooltip}\"}" diff --git a/fedora/waybar/style.css b/fedora/waybar/style.css deleted file mode 100644 index 4cffa06..0000000 --- a/fedora/waybar/style.css +++ /dev/null @@ -1,262 +0,0 @@ -/* Catppuccin Latte */ -@define-color rosewater #dc8a78; -@define-color flamingo #dd7878; -@define-color pink #ea76cb; -@define-color mauve #8839ef; -@define-color red #d20f39; -@define-color maroon #e64553; -@define-color peach #fe640b; -@define-color yellow #df8e1d; -@define-color green #40a02b; -@define-color teal #179299; -@define-color sky #04a5e5; -@define-color sapphire #209fb5; -@define-color blue #1e66f5; -@define-color lavender #7287fd; -@define-color text #4c4f69; -@define-color subtext1 #5c5f77; -@define-color subtext0 #6c6f85; -@define-color overlay2 #7c7f93; -@define-color overlay1 #8c8fa1; -@define-color overlay0 #9ca0b0; -@define-color surface2 #acb0be; -@define-color surface1 #bcc0cc; -@define-color surface0 #ccd0da; -@define-color base #eff1f5; -@define-color mantle #e6e9ef; -@define-color crust #dce0e8; - -* { - font-family: 'Noto Sans Mono', 'Symbols Nerd Font Mono', 'Symbols Nerd Font', 'Font Awesome 6 Free', monospace; - font-size: 15px; - font-weight: bold; -} - -window#waybar { - background-color: rgba(30, 30, 46, 0.72); - color: @text; - transition-property: background-color; - transition-duration: .5s; -} - -window#waybar.hidden { - opacity: 0.2; -} - -button { - box-shadow: inset 0 -3px transparent; - border: none; - border-radius: 16px; -} - -button:hover { - background: inherit; - box-shadow: inset 0 -2px @blue; -} - -/* Workspaces */ -#workspaces button { - min-height: 24px; - padding: 4px 8px; - background-color: #000000; - color: @overlay2; - border-radius: 16px; -} - -#workspaces button:hover { - background: #000000; -} - -#workspaces button.active { - color: @blue; - box-shadow: inset 0 -2px @blue; -} - -#workspaces button.urgent { - background-color: #000000; - color: @base; -} - -/* Common module styling */ -#window, -#custom-calendar, -#cpu, -#memory, -#disk, -#temperature, -#network, -#pulseaudio, -#wireplumber, -#tray, -#power-profiles-daemon, -#language, -#custom-gpu, -#custom-weather, -#privacy { - min-height: 24px; - padding: 4px 8px; - background-color: #000000; - border-radius: 16px; - color: @text; -} - -#workspaces button label, -#window label, -#custom-calendar label, -#cpu label, -#memory label, -#disk label, -#temperature label, -#network label, -#pulseaudio label, -#wireplumber label, -#tray label, -#power-profiles-daemon label, -#language label, -#custom-gpu label, -#custom-weather label, -#privacy label { - min-height: 24px; - padding: 0; - margin: 0; -} - -#window, -#workspaces { - margin: 0 4px; -} - -#window { - color: @text; -} - -/* Calendar/Clock */ -#custom-calendar { - color: @blue; - font-weight: bold; -} - -/* CPU */ -#cpu { - color: @green; -} - -/* Memory */ -#memory { - color: @mauve; -} - -/* Temperature */ -#temperature { - color: @peach; -} - -#temperature.critical { - color: @red; -} - -/* Network */ -#network { - color: @sapphire; - font-size: 20px; -} - -#network.disconnected { - color: @red; -} - -/* Pulseaudio */ -#pulseaudio { - color: @yellow; -} - -#pulseaudio.muted { - color: @overlay1; -} - -/* Language */ -#language { - color: @teal; - font-weight: bold; -} - -/* Power profiles */ -#power-profiles-daemon { - color: @subtext0; -} - -#power-profiles-daemon.performance { - color: @red; -} - -#power-profiles-daemon.balanced { - color: @blue; -} - -#power-profiles-daemon.power-saver { - color: @green; -} - -/* Mail */ -#custom-mail { - color: @lavender; -} - -#custom-mail.unread { - color: @red; -} - -/* Disk */ -#disk { - color: @flamingo; -} - -/* GPU */ -#custom-gpu { - color: @green; -} - -/* Weather */ -#custom-weather { - color: @sky; -} - -/* Privacy */ -#privacy { - background-color: transparent; - padding: 0; -} - -#privacy-item { - min-height: 24px; - padding: 4px 8px; - color: @base; - background-color: #000000; - border-radius: 16px; -} - -#privacy-item.screenshare { - background-color: #000000; -} - -#privacy-item.audio-in { - background-color: #000000; -} - -#privacy-item.audio-out { - background-color: #000000; -} - -/* Tray */ -#tray { - color: @text; -} - -#tray > .passive { - -gtk-icon-effect: dim; -} - -#tray > .needs-attention { - -gtk-icon-effect: highlight; - color: @red; -} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..021054e --- /dev/null +++ b/install.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +REPO_ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +FEDORA_ROOT="$REPO_ROOT/fedora" +CONFIG_ROOT="$HOME/.config" +LOCAL_BIN="$HOME/.local/bin" + +link_config() { + local source=$1 + local destination=$2 + + mkdir -p "$(dirname -- "$destination")" + if [[ -e "$destination" && ! -L "$destination" ]]; then + printf 'Refusing to replace existing path: %s\n' "$destination" >&2 + exit 1 + fi + ln -sfn -- "$source" "$destination" +} + +for name in niri fuzzel alacritty btop glow gtk-3.0 gtk-4.0 xsettingsd environment.d autostart; do + link_config "$FEDORA_ROOT/$name" "$CONFIG_ROOT/$name" +done + +link_config "$REPO_ROOT/nvim" "$CONFIG_ROOT/nvim" +link_config "$FEDORA_ROOT/quickshell/control-center" "$CONFIG_ROOT/quickshell/control-center" +link_config "$FEDORA_ROOT/systemd/user/quickshell-control-center.service" \ + "$CONFIG_ROOT/systemd/user/quickshell-control-center.service" +link_config "$FEDORA_ROOT/wallpapers/wallpaper.png" "$CONFIG_ROOT/wallpaper.png" + +mkdir -p "$LOCAL_BIN" + +for project in khal-calendar mail-counter; do + cargo build --release --manifest-path "$FEDORA_ROOT/$project/Cargo.toml" + install -m 755 "$FEDORA_ROOT/$project/target/release/$project" "$LOCAL_BIN/$project" +done + +systemctl --user daemon-reload +printf 'Installed Fedora and Neovim links; Rust binaries are in %s.\n' "$LOCAL_BIN" diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json index bffc866..f2b0fdc 100644 --- a/nvim/lazy-lock.json +++ b/nvim/lazy-lock.json @@ -1,30 +1,30 @@ { "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, - "LuaSnip": { "branch": "master", "commit": "dae4f5aaa3574bd0c2b9dd20fb9542a02c10471c" }, - "alabaster.nvim": { "branch": "main", "commit": "ae0c5f41c70b576f0678319e57fe47b2b288d2fc" }, + "LuaSnip": { "branch": "master", "commit": "0abc8f390b278c3b4aabc4c004ac8a088b65cf24" }, + "alabaster.nvim": { "branch": "main", "commit": "b902c73fabefc13583bfc0c18b28950ea8f6244f" }, "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, "cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" }, "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, - "crates.nvim": { "branch": "main", "commit": "ac9fa498a9edb96dc3056724ff69d5f40b898453" }, - "gitsigns.nvim": { "branch": "main", "commit": "9f3c6dd7868bcc116e9c1c1929ce063b978fa519" }, - "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, + "crates.nvim": { "branch": "main", "commit": "694357861ec9ebf12475ddcdd04ea45a0923c32d" }, + "gitsigns.nvim": { "branch": "main", "commit": "eb60cc7b94c46005237fd34170d76f3a089a90aa" }, + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, "lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" }, - "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "6c4830e37743b060d13c9269394176aea6a0fbc8" }, - "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, - "neo-tree.nvim": { "branch": "v3.x", "commit": "f3df514fff2bdd4318127c40470984137f87b62e" }, + "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "a4068c3ebd4cb335b25239e5ea35c22ee6007962" }, + "mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" }, + "neo-tree.nvim": { "branch": "v3.x", "commit": "ebd66767191714e008ce73b769518a763ff31bdc" }, "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, - "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" }, - "nvim-cmp": { "branch": "main", "commit": "da88697d7f45d16852c6b2769dc52387d1ddc45f" }, - "nvim-lspconfig": { "branch": "master", "commit": "5a855bcfec7973767a1a472335684bbd71d2fa2b" }, - "nvim-treesitter": { "branch": "main", "commit": "dc42c209f3820bdfaae0956f15de29689aa6b451" }, - "nvim-web-devicons": { "branch": "master", "commit": "746ffbb17975ebd6c40142362eee1b0249969c5c" }, + "nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" }, + "nvim-cmp": { "branch": "main", "commit": "2ffe79f1f021def8dd1fcd81deb16f1bb0d989f3" }, + "nvim-lspconfig": { "branch": "master", "commit": "d5b6e3db4c17b0146f63a2fc47e2027a754b2cb1" }, + "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" }, + "nvim-web-devicons": { "branch": "master", "commit": "09d1324e264c6950262dbe02a9bce2933a6800db" }, "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, - "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, - "rustaceanvim": { "branch": "master", "commit": "e9c5aaba16fead831379d5f44617547a90b913c7" }, - "telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, + "rustaceanvim": { "branch": "main", "commit": "e9c5aaba16fead831379d5f44617547a90b913c7" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" }, "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } diff --git a/nvim/lua/plugins/colorscheme.lua b/nvim/lua/plugins/colorscheme.lua index c46a0ba..f67628e 100644 --- a/nvim/lua/plugins/colorscheme.lua +++ b/nvim/lua/plugins/colorscheme.lua @@ -4,5 +4,28 @@ return { config = function() vim.o.background = "light" vim.cmd.colorscheme("alabaster") + + for _, group in ipairs({ + "Normal", + "NormalNC", + "NormalFloat", + "FloatBorder", + "SignColumn", + "FoldColumn", + "EndOfBuffer", + "LineNr", + "CursorLineNr", + "StatusLine", + "StatusLineNC", + "TabLine", + "TabLineFill", + "TabLineSel", + "NeoTreeNormal", + "NeoTreeNormalNC", + "NeoTreeEndOfBuffer", + "BufferLineFill", + }) do + vim.api.nvim_set_hl(0, group, { bg = "none" }) + end end, } diff --git a/nvim/lua/plugins/lualine.lua b/nvim/lua/plugins/lualine.lua index d525762..c2a706f 100644 --- a/nvim/lua/plugins/lualine.lua +++ b/nvim/lua/plugins/lualine.lua @@ -1,6 +1,11 @@ local layout = "EN" +local has_im_select = vim.fn.executable("im-select") == 1 local function update_layout() + if not has_im_select then + return + end + vim.system({ "im-select" }, { text = true }, function(result) if result.stdout then layout = result.stdout:find("Russian") and "RU" or "EN" @@ -10,7 +15,9 @@ 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)) +if has_im_select then + timer:start(0, 1000, vim.schedule_wrap(update_layout)) +end local function keyboard_layout() return layout