Compare commits

...
Author SHA1 Message Date
bgrollemanandClaude Sonnet 5.5 227ea2371b Cleanup dotfiles: niri float rules, tmux agent status, noctalia, claude settings
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 11:10:33 +02:00
bgrollemanandClaude Sonnet 5.5 cb80e100f4 Switch to Noctalia v5 and fix niri startup
Fix Mod+T bind (one action per bind), launch noctalia v5 from autostart,
port keybinds to `noctalia msg`, add config.toml, changelog and docs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 11:08:24 +02:00
bgrolleman 626bf30386 Add ~/.local/bin to fish PATH 2026-07-29 23:12:28 +02:00
bgrolleman be54b6b0ec Update niri settings for keybindings 2026-07-25 16:22:09 +02:00
bgrolleman f52815cc65 Add setup keychain ssh agent 2026-07-25 16:21:56 +02:00
bgrolleman 0835211ae9 Auto configure displays 2026-07-17 08:52:49 +02:00
bgrolleman 865a1923f5 Adding claude config 2026-07-04 14:47:22 +02:00
bgrolleman 279ca4a247 Merge branch 'main' of github.com:bgrolleman/dotfiles 2026-07-04 09:19:37 +02:00
bgrolleman 4f6643fd8e Add hotkeys for apps 2026-07-03 13:53:07 +02:00
bgrolleman 772c26f0b1 merge 2026-05-13 09:21:58 +02:00
bgrolleman 35349a426d Noctalia 2026-05-13 09:21:00 +02:00
19 changed files with 566 additions and 112 deletions

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
# Changelog
## 2026-10-10 (cleanup)
- Niri: floating windows open bottom-left by default; Picture-in-picture floats at a fixed offset.
- Noctalia v4 `settings.json`: move workspaces and system monitor to the right, add taskbar, enable idle.
- tmux: add per-window agent status indicator, 2s status refresh and a Prefix+Tab window switcher popup.
- Claude settings: pin model to sonnet, add herdr SessionStart hook, humanizer and ui-ux-pro-max plugins.
- CLAUDE.md: document claude/fish/kanshi linking, `workspaces.kdl` and the tmux helper script living outside the repo.
## 2026-10-10
- Fix niri login: Mod+T bind had three actions, niri rejected the config and fell back to defaults (no bar, no kanshi).
- Autostart now launches `noctalia` (v5, native) instead of `qs -c noctalia-shell` (v4, Quickshell/QML).
- Reason for the switch: Qt 6.12 broke noctalia-shell 4.x colours (`resolveColorKey is not a function`) and noctalia-qs was built on 6.11.
- Port all niri keybinds from `qs ... ipc call` to `noctalia msg` (launcher, lock, session, volume, media, brightness).
- Add `noctalia/config.toml`: theme, wallpaper, weather, idle, dock and bar layout ported from the old `settings.json`.
- Bar on the 5120px ultrawide (DP-1) is limited to ~70% width via a per-monitor `margin_ends` override.
- Restore previous wallpaper (`stellar-blade-2024-ultrawide.jpg`) on all outputs.
- Document the noctalia v4 to v5 migration (files, keybinds, bar, rollback) in `docs/noctalia-v5.md` and CLAUDE.md.
+68
View File
@@ -0,0 +1,68 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What This Repo Is
Personal dotfiles for a Linux desktop, currently running **Niri** (Wayland compositor) with **Noctalia** as the desktop shell. There are legacy X11 configs (i3, polybar, picom) that are no longer the primary setup.
## Deployment
Configs are deployed by symlinking into `~/.config/`, `~/.profile` and `~/.claude/settings.json` (fish is linked per file):
```bash
bash ~/.dotfiles/setup.sh
```
The script is idempotent — it skips links that already exist. After adding a new top-level config directory, add a `configlink <dirname>` line to `setup.sh`.
## Installing Desktop Applications
```bash
cd ansible.desktop
./install-desktop-toolsontech.sh
```
This installs ansible if missing, then runs the playbook. Tasks are split by category in `ansible.desktop/tasks/`.
## Architecture
### Niri (Wayland compositor)
`niri/config.kdl` is just includes — the real config lives in `niri/cfg/`:
- `input.kdl` — keyboard/mouse/touchpad settings
- `keybinds.kdl` — all keybindings
- `layout.kdl` — gaps, border, window sizing
- `display.kdl` — monitor layout and scaling
- `autostart.kdl` — apps launched on compositor start
- `rules.kdl` — window-specific rules
- `workspaces.kdl` — named workspaces
- `animation.kdl`, `misc.kdl` — tweaks
Edit the relevant split file, not `config.kdl` itself.
### Noctalia (desktop shell / bar)
Runs **Noctalia v5** (`noctalia`, native). Config is `noctalia/config.toml` (TOML, hot-reloaded); validate with `noctalia config validate`.
`noctalia/settings.json` is the legacy v4 config (kept for rollback, still tweaked occasionally). See `docs/noctalia-v5.md` for details and `CHANGELOG.md` for history.
### Neovim
Uses **LazyVIM** framework. Entry point is `nvim/init.lua` which bootstraps lazy.nvim via `nvim/lua/config/lazy.lua`.
- `nvim/lua/config/` — core config (options, keymaps, autocmds)
- `nvim/lua/plugins/` — plugin overrides/additions on top of LazyVIM defaults
- `nvim/lua/colorschemes/` — colorscheme configs
LazyVIM handles most plugin management; only deviations from LazyVIM defaults need entries in `lua/plugins/`.
### tmux
`tmux/tmux.conf` + catppuccin theme as a git submodule at `tmux/plugins/catppuccin/tmux`. The agent-status indicators call `~/.local/bin/tmux-window-agent-status`, which is **not** in this repo. After cloning, initialize the submodule:
```bash
git submodule update --init
```
### Shell / profile
`fish/` holds the fish config (`config.fish`, `conf.d/ssh-keychain.fish`); machine-specific vars go in untracked `~/.config/fish/local.fish`.
`profile` is symlinked to `~/.profile`. It sets up SSH keys via `keychain` and defines the `notes` alias (attaches/creates a tmux session with nvim opening `~/Notes/Personal`).
`zoxide.bash` provides shell integration for zoxide (directory jumping) — sourced separately, not via `profile`.
+81 -11
View File
@@ -1,16 +1,9 @@
{ {
"theme": "dark", "permissions": {
"defaultMode": "auto"
},
"model": "sonnet",
"hooks": { "hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude' 'Task complete' --icon=dialog-information 2>/dev/null || true"
}
]
}
],
"Notification": [ "Notification": [
{ {
"hooks": [ "hooks": [
@@ -20,6 +13,83 @@
} }
] ]
} }
],
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash '/home/bgrolleman/.claude/hooks/herdr-agent-state.sh' session",
"timeout": 10
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude' 'Task complete' --icon=dialog-information 2>/dev/null || true"
}
]
}
] ]
},
"statusLine": {
"type": "command",
"command": "bash \"/home/bgrolleman/.claude/statusline-command.sh\""
},
"enabledPlugins": {
"frontend-design@claude-plugins-official": true,
"humanizer@humanizer": true,
"lua-lsp@claude-plugins-official": true,
"ponytail@ponytail": true,
"ui-ux-pro-max@ui-ux-pro-max-skill": true
},
"extraKnownMarketplaces": {
"caveman": {
"source": {
"source": "github",
"repo": "juliusbrussee/caveman"
}
},
"humanizer": {
"source": {
"source": "github",
"repo": "blader/humanizer"
}
},
"ponytail": {
"source": {
"source": "github",
"repo": "DietrichGebert/ponytail"
}
},
"ui-ux-pro-max-skill": {
"source": {
"source": "github",
"repo": "nextlevelbuilder/ui-ux-pro-max-skill"
}
}
},
"effortLevel": "high",
"advisorModel": "opus",
"voice": {
"enabled": true,
"mode": "hold"
},
"theme": "dark",
"agentPushNotifEnabled": true,
"skipAutoPermissionPrompt": true,
"voiceEnabled": true,
"mcpServers": {
"comfyui-image-gen": {
"args": [
"/home/bgrolleman/Project/ComfyUI/mcp_server.py"
],
"command": "/home/bgrolleman/Project/ComfyUI/.venv/bin/python"
}
} }
} }
+74
View File
@@ -0,0 +1,74 @@
#!/bin/bash
# Claude Code status line
# Shows: model display name, a progress bar for context-window tokens
# remaining in this session, current git branch, active subagent (if any),
# and enabled plugins (read from ~/.claude/settings.json).
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
cwd=$(echo "$input" | jq -r '.workspace.current_dir // empty')
remaining=$(echo "$input" | jq -r '.context_window.remaining_percentage // empty')
agent_name=$(echo "$input" | jq -r '.agent.name // empty')
# --- Colors (kept modest; Claude Code renders the status line dimmed) ---
c_model='\033[36m' # cyan
c_bar='\033[32m' # green
c_branch='\033[33m' # yellow
c_agent='\033[35m' # magenta
c_plugin='\033[34m' # blue
c_reset='\033[0m'
# --- Git branch (skip optional locks; silent if not a repo) ---
branch=""
if [ -n "$cwd" ]; then
branch=$(git --no-optional-locks -C "$cwd" branch --show-current 2>/dev/null)
fi
# --- Enabled plugins, read from settings.json (not present on stdin) ---
settings_file="$HOME/.claude/settings.json"
plugins=""
if [ -f "$settings_file" ]; then
plugins=$(jq -r '.enabledPlugins // {} | to_entries[] | select(.value == true) | .key | split("@")[0]' "$settings_file" 2>/dev/null | paste -sd, -)
fi
# --- Context-window remaining-tokens progress bar ---
bar=""
if [ -n "$remaining" ]; then
pct=${remaining%.*}
[ -z "$pct" ] && pct=0
[ "$pct" -lt 0 ] 2>/dev/null && pct=0
[ "$pct" -gt 100 ] 2>/dev/null && pct=100
total_blocks=10
filled=$(( pct * total_blocks / 100 ))
[ "$filled" -gt "$total_blocks" ] && filled=$total_blocks
[ "$filled" -lt 0 ] && filled=0
empty=$(( total_blocks - filled ))
bar="["
i=0
while [ "$i" -lt "$filled" ]; do bar="${bar}█"; i=$((i + 1)); done
i=0
while [ "$i" -lt "$empty" ]; do bar="${bar}░"; i=$((i + 1)); done
bar="${bar}] ${pct}% left"
fi
# --- Assemble the status line ---
printf "${c_model}%s${c_reset}" "$model"
if [ -n "$bar" ]; then
printf " ${c_bar}%s${c_reset}" "$bar"
fi
if [ -n "$branch" ]; then
printf " ${c_branch}git:%s${c_reset}" "$branch"
fi
if [ -n "$agent_name" ]; then
printf " ${c_agent}agent:%s${c_reset}" "$agent_name"
fi
if [ -n "$plugins" ]; then
printf " ${c_plugin}plugins:%s${c_reset}" "$plugins"
fi
printf '\n'
+36
View File
@@ -0,0 +1,36 @@
# Noctalia v5
Noctalia v5 (`noctalia` package) is a native Wayland shell with no Qt dependency. It replaces v4
(`noctalia-shell` + `noctalia-qs`, Quickshell/QML), which broke on Qt 6.12.
## Files
- `noctalia/config.toml` - hand-edited config, hot-reloaded. Linked to `~/.config/noctalia/config.toml`.
- `~/.local/state/noctalia/settings.toml` - GUI-managed overrides and runtime state (not in this repo).
- `noctalia/settings.json` - old v4 config, kept for reference or fallback.
Validate after editing: `noctalia config validate`. Open the settings GUI: `noctalia msg settings-open`.
## Startup and keybinds
- Started from `niri/cfg/autostart.kdl` with `spawn-at-startup "noctalia"`.
- Keybinds in `niri/cfg/keybinds.kdl` call `noctalia msg <command>`; list them with `noctalia msg --help`.
- Panel ids for `panel-toggle`: clipboard, control-center, launcher, polkit, session, tray-drawer, wallpaper.
- Wallpaper is set with `noctalia msg wallpaper-set [output] <path>` and persists.
## Bar
- Layout is the `start`, `center` and `end` lists in `[bar.main]`.
- `[bar.main.monitor.ultrawide]` matches DP-1 and sets `margin_ends = 768`, which gives about 70% width on 5120px.
Formula: `(monitor_width - wanted_width) / 2`.
## Not ported from v4
- System monitor widget (widget id unknown in v5), per-widget options such as hover-only labels.
- v4 plugins (`polkit-agent`): v5 has a built-in `polkit` panel instead.
- The v4 bar only ran on DP-1; v5 runs on every output.
## Rolling back
Set autostart to `qs -c noctalia-shell` again and restore the `qs ... ipc call` binds from git history.
This needs a `noctalia-shell` that works with the installed Qt version.
+15
View File
@@ -0,0 +1,15 @@
# Start keychain and source SSH agent variables for all private keys in ~/.ssh
if status is-interactive
if type -q keychain
set -l _ssh_keys
for _pub in ~/.ssh/*.pub
set -l _key (string replace -r '\.pub$' '' $_pub)
if test -f $_key
set -a _ssh_keys $_key
end
end
if test (count $_ssh_keys) -gt 0
keychain --eval --quiet $_ssh_keys | source
end
end
end
+7
View File
@@ -0,0 +1,7 @@
fish_add_path ~/.local/bin
# Machine-specific config (secrets, local overrides) — not tracked in dotfiles
if test -f ~/.config/fish/local.fish
source ~/.config/fish/local.fish
end
alias davinci-resolve-studio 'env QT_QPA_PLATFORM=xcb /usr/bin/davinci-resolve-studio'
+8
View File
@@ -0,0 +1,8 @@
profile ultrawide-hdmi {
output "DP-1" mode 5120x1440 position 0,0 scale 1
output "HDMI-A-1" mode 1920x1080 position 1600,1440 scale 1
}
profile ultrawide {
output "DP-1" mode 5120x1440 position 0,0 scale 1
}
+2 -1
View File
@@ -1,4 +1,5 @@
// ────────────── Startup Applications ────────────── // ────────────── Startup Applications ──────────────
// https://github.com/YaLTeR/niri/wiki/Configuration:-Miscellaneous#spawn-sh-at-startup // https://github.com/YaLTeR/niri/wiki/Configuration:-Miscellaneous#spawn-sh-at-startup
spawn-sh-at-startup "qs -c noctalia-shell" spawn-at-startup "noctalia"
spawn-at-startup "kanshi"
+1 -1
View File
@@ -12,7 +12,7 @@ input {
} }
touchpad { touchpad {
//tap // Enable tap-to-click tap // Enable tap-to-click
dwt dwt
scroll-method "two-finger" scroll-method "two-finger"
tap-button-map "left-right-middle" tap-button-map "left-right-middle"
+31 -28
View File
@@ -9,32 +9,36 @@ binds {
//Mod+Shift+ESCAPE { show-hotkey-overlay; } //Mod+Shift+ESCAPE { show-hotkey-overlay; }
Mod+h { show-hotkey-overlay; } Mod+h { show-hotkey-overlay; }
Mod+Shift+S { spawn-sh "flameshot gui"; } Mod+Shift+S { spawn-sh "grim -g \"$(slurp)\" - | satty --filename - -o ~/Pictures/Screenshots/satty-%Y%m%d-%H%M%S.png --copy-command wl-copy --actions-on-enter save-to-clipboard --save-after-copy"; }
// ─── Applications ─── // ─── Applications ───
Alt+Return hotkey-overlay-title="Open Terminal: Alacritty" { spawn "alacritty"; } Alt+Return hotkey-overlay-title="Open Terminal: Alacritty" { spawn "alacritty"; }
//Mod+CTRL+Return hotkey-overlay-title="Open App Launcher: noctalia launcher" { spawn-sh "qs -c noctalia-shell ipc call launcher toggle"; } Mod+G hotkey-overlay-title="Focus: Gmail" { spawn-sh "$HOME/.config/niri/focus-or-launch.sh chrome-fmgjjmmmlfnkbppncabfkddbjimcfncm-Default /opt/helium-browser-bin/helium-wrapper --profile-directory=Default --app-id=fmgjjmmmlfnkbppncabfkddbjimcfncm"; }
Alt+Space hotkey-overlay-title="Open App Launcher: noctalia launcher" { spawn-sh "qs -c noctalia-shell ipc call launcher toggle"; } Mod+W hotkey-overlay-title="Focus: WhatsApp" { spawn-sh "$HOME/.config/niri/focus-or-launch.sh chrome-hnpfjngllnobngcgfapefoaidbinmjnm-Default /opt/helium-browser-bin/helium-wrapper --profile-directory=Default --app-id=hnpfjngllnobngcgfapefoaidbinmjnm"; }
Mod+D hotkey-overlay-title="Focus: Todoist" { spawn-sh "$HOME/.config/niri/focus-or-launch.sh chrome-dlgohinmglaoopaiplliaecdpmnepmga-Default /opt/helium-browser-bin/helium-wrapper --profile-directory=Default --app-id=dlgohinmglaoopaiplliaecdpmnepmga"; }
//Mod+CTRL+Return hotkey-overlay-title="Open App Launcher: noctalia launcher" { spawn-sh "noctalia msg panel-toggle launcher"; }
Alt+Space hotkey-overlay-title="Open App Launcher: noctalia launcher" { spawn-sh "noctalia msg panel-toggle launcher"; }
Alt+Shift+Space hotkey-overlay-title="Open Window Search: noctalia launcher" { spawn-sh "noctalia msg window-switcher"; }
Mod+B hotkey-overlay-title="Open Browser: helium" { spawn "helium-browser"; } Mod+B hotkey-overlay-title="Open Browser: helium" { spawn "helium-browser"; }
Mod+L hotkey-overlay-title="Lock Screen: noctalia lock" { spawn-sh "qs -c noctalia-shell ipc call lockScreen lock"; } Mod+L hotkey-overlay-title="Lock Screen: noctalia lock" { spawn-sh "noctalia msg session lock"; }
Mod+Shift+Q hotkey-overlay-title="Session Menu: noctalia sessionMenu" { spawn-sh "qs -c noctalia-shell ipc call sessionMenu toggle"; } Mod+Shift+Q hotkey-overlay-title="Session Menu: noctalia sessionMenu" { spawn-sh "noctalia msg panel-toggle session"; }
// Please choose your own file manager. // Please choose your own file manager.
Mod+E hotkey-overlay-title="File Manager: Nautilus" { spawn "nautilus"; } Mod+E hotkey-overlay-title="File Manager: Nautilus" { spawn "nautilus"; }
// ─── Media Controls ─── // ─── Media Controls ───
XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume increase"; } XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "noctalia msg volume-up"; }
XF86AudioLowerVolume allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume decrease"; } XF86AudioLowerVolume allow-when-locked=true { spawn-sh "noctalia msg volume-down"; }
XF86AudioMute allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume muteOutput"; } XF86AudioMute allow-when-locked=true { spawn-sh "noctalia msg volume-mute"; }
XF86AudioMicMute allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call volume muteInput"; } XF86AudioMicMute allow-when-locked=true { spawn-sh "noctalia msg mic-mute"; }
XF86AudioNext allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media next"; } XF86AudioNext allow-when-locked=true { spawn-sh "noctalia msg media next"; }
XF86AudioPrev allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media previous"; } XF86AudioPrev allow-when-locked=true { spawn-sh "noctalia msg media previous"; }
XF86AudioPlay allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; } XF86AudioPlay allow-when-locked=true { spawn-sh "noctalia msg media toggle"; }
XF86AudioPause allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; } XF86AudioPause allow-when-locked=true { spawn-sh "noctalia msg media toggle"; }
// ─── Brightness Controls ─── // ─── Brightness Controls ───
XF86MonBrightnessUp allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call brightness increase"; } XF86MonBrightnessUp allow-when-locked=true { spawn-sh "noctalia msg brightness-up"; }
XF86MonBrightnessDown allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call brightness decrease"; } XF86MonBrightnessDown allow-when-locked=true { spawn-sh "noctalia msg brightness-down"; }
// ─── Window Movement and Focus ─── // ─── Window Movement and Focus ───
Alt+H { focus-column-left; } Alt+H { focus-column-left; }
@@ -98,22 +102,22 @@ binds {
// Mod+CTRL+Shift+WheelScrollDown { move-column-right; } // Mod+CTRL+Shift+WheelScrollDown { move-column-right; }
// Mod+CTRL+Shift+WheelScrollUp { move-column-left; } // Mod+CTRL+Shift+WheelScrollUp { move-column-left; }
Alt+1 { focus-workspace 1; } Alt+1 { focus-workspace "1"; }
Alt+2 { focus-workspace 2; } Alt+2 { focus-workspace "2"; }
Alt+3 { focus-workspace 3; } Alt+3 { focus-workspace "3"; }
Alt+4 { focus-workspace 4; } Alt+4 { focus-workspace "4"; }
Alt+5 { focus-workspace 5; } Alt+5 { focus-workspace "5"; }
Alt+6 { focus-workspace 6; } Alt+6 { focus-workspace "6"; }
Alt+7 { focus-workspace 7; } Alt+7 { focus-workspace 7; }
Alt+8 { focus-workspace 8; } Alt+8 { focus-workspace 8; }
Alt+9 { focus-workspace 9; } Alt+9 { focus-workspace 9; }
Alt+Shift+1 { move-column-to-workspace 1; } Alt+Shift+1 { move-column-to-workspace "1"; }
Alt+Shift+2 { move-column-to-workspace 2; } Alt+Shift+2 { move-column-to-workspace "2"; }
Alt+Shift+3 { move-column-to-workspace 3; } Alt+Shift+3 { move-column-to-workspace "3"; }
Alt+Shift+4 { move-column-to-workspace 4; } Alt+Shift+4 { move-column-to-workspace "4"; }
Alt+Shift+5 { move-column-to-workspace 5; } Alt+Shift+5 { move-column-to-workspace "5"; }
Alt+Shift+6 { move-column-to-workspace 6; } Alt+Shift+6 { move-column-to-workspace "6"; }
Alt+Shift+7 { move-column-to-workspace 7; } Alt+Shift+7 { move-column-to-workspace 7; }
Alt+Shift+8 { move-column-to-workspace 8; } Alt+Shift+8 { move-column-to-workspace 8; }
Alt+Shift+9 { move-column-to-workspace 9; } Alt+Shift+9 { move-column-to-workspace 9; }
@@ -132,7 +136,6 @@ binds {
// ─── Modes ─── // ─── Modes ───
Mod+T { toggle-window-floating; } Mod+T { toggle-window-floating; }
Mod+F { fullscreen-window; } Mod+F { fullscreen-window; }
Mod+W { toggle-column-tabbed-display; }
// ─── Screenshots ─── // ─── Screenshots ───
CTRL+Shift+1 { screenshot; } CTRL+Shift+1 { screenshot; }
+3 -1
View File
@@ -5,7 +5,9 @@
background-color "transparent" // <- needed for noctalia-shell to set wallpaper background-color "transparent" // <- needed for noctalia-shell to set wallpaper
//default-column-width { proportion 0.95; } //default-column-width { proportion 0.95; }
default-column-width { proportion 0.40; } //default-column-width { proportion 0.40; }
//default-column-width {}
default-column-width { fixed 1200; }
preset-column-widths { preset-column-widths {
proportion 0.33333 proportion 0.33333
+7
View File
@@ -1,6 +1,7 @@
window-rule { window-rule {
geometry-corner-radius 5 // Set every window radius to 20 geometry-corner-radius 5 // Set every window radius to 20
clip-to-geometry true clip-to-geometry true
default-floating-position x=10 y=10 relative-to="bottom-left"
} }
// if you use steam you will probably like these // if you use steam you will probably like these
@@ -16,6 +17,12 @@
open-focused false open-focused false
} }
window-rule {
match title="^Picture-in-picture$"
open-floating true
default-floating-position x=50 y=50 relative-to="bottom-left"
}
layer-rule { layer-rule {
match namespace="^noctalia-wallpaper*" match namespace="^noctalia-wallpaper*"
place-within-backdrop true place-within-backdrop true
+18 -2
View File
@@ -1,2 +1,18 @@
workspace "browser" workspace "1" {
workspace "chat" open-on-output "DP-1"
}
workspace "2" {
open-on-output "DP-1"
}
workspace "3" {
open-on-output "DP-1"
}
workspace "4" {
open-on-output "DP-1"
}
workspace "5" {
open-on-output "DP-1"
}
workspace "6" {
open-on-output "HDMI-A-1"
}
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# Focus an existing window by app-id, or launch it if not found.
# If the target window is already focused, return to the previous window.
# Usage: focus-or-launch.sh <app-id> <launch-command...>
APP_ID="$1"
shift
WINDOWS=$(niri msg -j windows)
FOCUSED_ID=$(echo "$WINDOWS" | jq -r '.[] | select(.is_focused == true) | .id')
TARGET_ID=$(echo "$WINDOWS" | jq -r --arg app "$APP_ID" '.[] | select(.app_id == $app) | .id' | head -1)
PREV_FILE="/tmp/niri-focus-prev-${APP_ID}"
if [ "$FOCUSED_ID" = "$TARGET_ID" ]; then
if [ -f "$PREV_FILE" ]; then
niri msg action focus-window --id "$(cat "$PREV_FILE")" 2>/dev/null || true
fi
else
echo "$FOCUSED_ID" > "$PREV_FILE"
if [ -n "$TARGET_ID" ]; then
niri msg action focus-window --id "$TARGET_ID"
else
exec "$@"
fi
fi
+56
View File
@@ -0,0 +1,56 @@
# Ported from the old settings.json (noctalia-shell 4.x). Unlisted keys use defaults.
[theme]
mode = "dark"
source = "builtin"
builtin = "Catppuccin"
[wallpaper]
enabled = true
fill_mode = "crop"
transition = ["fade", "disc", "stripes", "wipe", "honeycomb"]
transition_duration = 1500
directory = "/home/bgrolleman/Documents/Resources/Backgrounds"
[weather]
enabled = true
unit = "celsius"
[location]
address = "Amersfoort, The Netherlands"
[idle.behavior.lock]
timeout = 660
action = "lock"
enabled = true
[idle.behavior.screen-off]
timeout = 600
action = "screen_off"
enabled = true
[dock]
enabled = true
position = "left"
auto_hide = true
[bar.main]
position = "top"
background_opacity = 0.93
capsule = true
margin_ends = 4
margin_edge = 4
widget_spacing = 6
start = ["launcher", "taskbar"]
center = ["clock", "media"]
end = ["workspaces", "tray", "network", "bluetooth", "notifications", "battery", "volume", "brightness", "control-center"]
[widget.clock]
format = "{:%H:%M %a, %b %d}"
tooltip_format = "{:%H:%M %a, %b %d}"
# 70% of the 5120px ultrawide: (5120 - 3584) / 2
[bar.main.monitor.ultrawide]
match = "DP-1"
margin_ends = 768
+74 -59
View File
@@ -60,6 +60,7 @@
"middleClickCommand": "", "middleClickCommand": "",
"middleClickFollowMouse": false, "middleClickFollowMouse": false,
"monitors": [ "monitors": [
"DP-1"
], ],
"mouseWheelAction": "none", "mouseWheelAction": "none",
"mouseWheelWrap": true, "mouseWheelWrap": true,
@@ -86,6 +87,22 @@
"id": "Clock", "id": "Clock",
"tooltipFormat": "HH:mm ddd, MMM dd", "tooltipFormat": "HH:mm ddd, MMM dd",
"useCustomFont": false "useCustomFont": false
},
{
"compactMode": false,
"hideMode": "hidden",
"hideWhenIdle": true,
"id": "MediaMini",
"maxWidth": 500,
"panelShowAlbumArt": true,
"scrollingMode": "hover",
"showAlbumArt": true,
"showArtistFirst": true,
"showProgressRing": true,
"showVisualizer": false,
"textColor": "none",
"useFixedWidth": false,
"visualizerType": "linear"
} }
], ],
"left": [ "left": [
@@ -99,6 +116,42 @@
"id": "Launcher", "id": "Launcher",
"useDistroLogo": false "useDistroLogo": false
}, },
{
"colorizeIcons": false,
"hideMode": "hidden",
"iconScale": 0.8,
"id": "Taskbar",
"maxTaskbarWidth": 40,
"onlyActiveWorkspaces": true,
"onlySameOutput": true,
"showPinnedApps": false,
"showTitle": true,
"smartWidth": true,
"titleWidth": 120
}
],
"right": [
{
"characterCount": 2,
"colorizeIcons": false,
"emptyColor": "secondary",
"enableScrollWheel": true,
"focusedColor": "primary",
"followFocusedScreen": false,
"fontWeight": "bold",
"groupedBorderOpacity": 1,
"hideUnoccupied": true,
"iconScale": 0.8,
"id": "Workspace",
"labelMode": "name",
"occupiedColor": "secondary",
"pillSize": 0.6,
"showApplications": true,
"showApplicationsHover": false,
"showBadge": true,
"showLabelsOnlyWhenOccupied": true,
"unfocusedIconsOpacity": 1
},
{ {
"compactMode": true, "compactMode": true,
"diskPath": "/", "diskPath": "/",
@@ -121,56 +174,6 @@
"useMonospaceFont": true, "useMonospaceFont": true,
"usePadding": false "usePadding": false
}, },
{
"compactMode": false,
"hideMode": "hidden",
"hideWhenIdle": false,
"id": "MediaMini",
"maxWidth": 145,
"panelShowAlbumArt": true,
"scrollingMode": "hover",
"showAlbumArt": true,
"showArtistFirst": true,
"showProgressRing": true,
"showVisualizer": false,
"textColor": "none",
"useFixedWidth": false,
"visualizerType": "linear"
},
{
"characterCount": 2,
"colorizeIcons": false,
"emptyColor": "secondary",
"enableScrollWheel": true,
"focusedColor": "primary",
"followFocusedScreen": false,
"fontWeight": "bold",
"groupedBorderOpacity": 1,
"hideUnoccupied": false,
"iconScale": 0.8,
"id": "Workspace",
"labelMode": "index",
"occupiedColor": "secondary",
"pillSize": 0.6,
"showApplications": false,
"showApplicationsHover": false,
"showBadge": true,
"showLabelsOnlyWhenOccupied": true,
"unfocusedIconsOpacity": 1
},
{
"colorizeIcons": false,
"hideMode": "visible",
"id": "ActiveWindow",
"maxWidth": 350,
"scrollingMode": "hover",
"showIcon": true,
"showText": true,
"textColor": "none",
"useFixedWidth": true
}
],
"right": [
{ {
"blacklist": [ "blacklist": [
], ],
@@ -182,6 +185,18 @@
"pinned": [ "pinned": [
] ]
}, },
{
"displayMode": "onhover",
"iconColor": "none",
"id": "Network",
"textColor": "none"
},
{
"displayMode": "onhover",
"iconColor": "none",
"id": "Bluetooth",
"textColor": "none"
},
{ {
"hideWhenZero": false, "hideWhenZero": false,
"hideWhenZeroUnread": false, "hideWhenZeroUnread": false,
@@ -341,23 +356,23 @@
"groupClickAction": "cycle", "groupClickAction": "cycle",
"groupContextMenuMode": "extended", "groupContextMenuMode": "extended",
"groupIndicatorStyle": "dots", "groupIndicatorStyle": "dots",
"inactiveIndicators": false, "inactiveIndicators": true,
"indicatorColor": "primary", "indicatorColor": "primary",
"indicatorOpacity": 0.6, "indicatorOpacity": 0.6,
"indicatorThickness": 3, "indicatorThickness": 3,
"launcherIcon": "", "launcherIcon": "",
"launcherIconColor": "none", "launcherIconColor": "none",
"launcherPosition": "end", "launcherPosition": "start",
"launcherUseDistroLogo": false, "launcherUseDistroLogo": true,
"monitors": [ "monitors": [
], ],
"onlySameOutput": true, "onlySameOutput": true,
"pinnedApps": [ "pinnedApps": [
], ],
"pinnedStatic": false, "pinnedStatic": true,
"position": "bottom", "position": "left",
"showDockIndicator": true, "showDockIndicator": true,
"showLauncherIcon": false, "showLauncherIcon": true,
"sitOnFrame": false, "sitOnFrame": false,
"size": 1 "size": 1
}, },
@@ -440,7 +455,7 @@
}, },
"idle": { "idle": {
"customCommands": "[]", "customCommands": "[]",
"enabled": false, "enabled": true,
"fadeDuration": 5, "fadeDuration": 5,
"lockCommand": "", "lockCommand": "",
"lockTimeout": 660, "lockTimeout": 660,
@@ -450,7 +465,7 @@
"screenOffCommand": "", "screenOffCommand": "",
"screenOffTimeout": 600, "screenOffTimeout": 600,
"suspendCommand": "", "suspendCommand": "",
"suspendTimeout": 1800 "suspendTimeout": 0
}, },
"location": { "location": {
"analogClockInCalendar": false, "analogClockInCalendar": false,
@@ -476,7 +491,7 @@
"bluetoothRssiPollingEnabled": false, "bluetoothRssiPollingEnabled": false,
"disableDiscoverability": false, "disableDiscoverability": false,
"networkPanelView": "wifi", "networkPanelView": "wifi",
"wifiDetailsViewMode": "grid" "wifiDetailsViewMode": "list"
}, },
"nightLight": { "nightLight": {
"autoSchedule": true, "autoSchedule": true,
+28
View File
@@ -14,6 +14,20 @@ link() {
ln -s "$2" "$1" ln -s "$2" "$1"
fi fi
} }
# Like link(), but backs up existing regular files instead of skipping them
smartlink() {
local target="$1" source="$2"
echo "Linking $target to $source"
if [ -L "$target" ]; then
: # already a symlink, nothing to do
elif [ -e "$target" ]; then
mv "$target" "${target}.bak"
echo " Backed up existing file to ${target}.bak"
ln -s "$source" "$target"
else
ln -s "$source" "$target"
fi
}
configlink() { configlink() {
link ~/.config/$1 ~/.dotfiles/$1 link ~/.config/$1 ~/.dotfiles/$1
} }
@@ -29,6 +43,20 @@ configlink polybar
configlink picom.conf configlink picom.conf
configlink niri configlink niri
configlink noctalia configlink noctalia
configlink kanshi
checkdir ~/.claude checkdir ~/.claude
link ~/.claude/settings.json ~/.dotfiles/claude/settings.json link ~/.claude/settings.json ~/.dotfiles/claude/settings.json
# Fish shell config
checkdir ~/.config/fish
checkdir ~/.config/fish/conf.d
smartlink ~/.config/fish/config.fish ~/.dotfiles/fish/config.fish
link ~/.config/fish/conf.d/ssh-keychain.fish ~/.dotfiles/fish/conf.d/ssh-keychain.fish
# Migrate BW_SESSION and other machine-specific fish vars to local.fish
if [ -f ~/.config/fish/config.fish.bak ] && [ ! -f ~/.config/fish/local.fish ]; then
echo " Migrating machine-specific config from config.fish.bak to local.fish"
grep -v '^#' ~/.config/fish/config.fish.bak | grep -v '^\s*$' > ~/.config/fish/local.fish
echo " Review ~/.config/fish/local.fish and remove anything now handled by dotfiles"
fi
+12 -9
View File
@@ -14,19 +14,22 @@ set -g @catppuccin_window_status_style "slanted"
# Load catppuccin # Load catppuccin
run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux
# Make the status line pretty and add some modules # Status line on top (tmux only supports top/bottom, no vertical sidebar)
set-option -g status-position top set-option -g status-position top
set -g status-right-length 100 set -g status-right-length 100
set -g status-left-length 100 set -g status-left-length 100
set -g status-left "#[fg=#{@thm_teal},bg=#{@thm_crust}]#[fg=#{@thm_crust},bg=#{@thm_teal}] #(hostname -s) " set -g status-left "#[fg=#{@thm_teal},bg=#{@thm_crust}]#[fg=#{@thm_crust},bg=#{@thm_teal}] #(hostname -s) "
#set -g status-left "#[fg=$thm_green,bg=$thm_bg,nobold,nounderscore,noitalics]#[fg=$thm_bg,bg=$thm_green,nobold,nounderscore,noitalics] #[fg=$thm_fg,bg=$thm_bg]#(hostname -s) "
set -g status-right "#{E:@catppuccin_status_application}" set -g status-right "#{E:@catppuccin_status_application}"
#set -agF status-right "#{E:@catppuccin_status_cpu}"
set -ag status-right "#{E:@catppuccin_status_session}" set -ag status-right "#{E:@catppuccin_status_session}"
#set -ag status-right "#{E:@catppuccin_status_uptime}"
#set -agF status-right "#{E:@catppuccin_status_battery}"
#run ~/.config/tmux/plugins/tmux-plugins/tmux-cpu/cpu.tmux # Per-window agent indicator: 🤖 = busy, ⏸ = waiting for input
#run ~/.config/tmux/plugins/tmux-plugins/tmux-battery/battery.tmux set -g @catppuccin_window_text " #W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#I')"
set -g @catppuccin_window_current_text " #W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#I')"
# Refresh status regularly so agent indicators stay current
set -g status-interval 2
# Vertical window switcher ("sidebar"): prefix+Tab opens a popup listing all
# windows top-to-bottom with agent status; Enter jumps to the selected window
bind-key Tab choose-tree -Zw -F "#{?window_format,#W#(~/.local/bin/tmux-window-agent-status '#{session_name}' '#{window_index}'),}"