Skip to content

Commit a3d0d78

Browse files
committed
feat: optimize system configs, add custom viewers, and configure Kiview previews
1 parent ff59c95 commit a3d0d78

37 files changed

Lines changed: 416 additions & 218 deletions

.chezmoignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ bin/chezmoi
99
.cursorrules
1010
.directory
1111
CLAUDE.md
12-
install_toshy.sh
1312
apply_dns.sh
1413
setup_stationary.sh
1514
.agents/
1615
README.md
1716
LICENSE
1817
AGENTS.md
1918
scripts/
19+
20+
{{ if ne .chezmoi.os "darwin" }}
21+
Library/**
22+
{{ end }}

AGENTS.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ If you are an AI assistant (Cursor, Claude Code, etc.), you MUST adhere to the f
1313
## 2. Privilege Escalation
1414
- On **Linux**, when running commands that require root or administrator privileges, **ALWAYS use `pkexec` instead of `sudo`**. The user cannot type their password in the IDE terminal, so a GUI prompt via `pkexec` is required.
1515
- On **macOS**, `pkexec` does not exist, so you may use standard `sudo` (or `osascript`) as macOS handles terminal authentication differently.
16+
- **Selective Phase Execution**: When running the setup scripts (`run_once_setup_fedora.sh`), avoid running blindly with `AUTO_YES=1` in the background if root authorizations are required. Instead, run interactively and selectively authorize only the phases that contain the modified files (e.g. Phase 2 for general/flatpak package updates) while declining others (like Phase 1/Phase 3) to minimize prompt overhead and privilege escalation failures.
1617

1718
## 3. Scripting & Code Quality
1819
- **Idempotency**: All bash scripts (like `bootstrap.sh`) must be safely repeatable. Always check if a command or directory exists before trying to install it.
@@ -55,3 +56,17 @@ To achieve a macOS-like modifier experience on PC keyboard hardware, the followi
5556
## 9. KDE Plasma Style Theme Management
5657
- Plasma panel theme styles (Breeze Light/Dark) are separate from standard window color schemes and are saved in `plasmarc`.
5758
- Because Chezmoi template deployment completely overwrites `plasmarc` (often wiping out the `[Theme]` group), you must use the `run_after_setup_plasma.sh` hook. This script reads the active `kdeglobals` color scheme and dynamically re-writes the matching Plasma style (`breeze-light` or `breeze-dark`) back into `plasmarc` to guarantee the panel colors stay in sync after every apply.
59+
60+
## 10. Flatpak Applications, Settings & Overrides
61+
- **Permission Overrides**: Custom Flatpak permission overrides (such as browser integrations, global menus, or GTK theme access for apps like Todoist) MUST be tracked under `dot_local/share/flatpak/overrides/` to maintain desktop consistency.
62+
- **EasyEffects Syncing**: Because EasyEffects is a Flatpak, it sandboxes its configs. Its data directories (`~/.var/app/com.github.wwmm.easyeffects/data/easyeffects` and `~/.var/app/com.github.wwmm.easyeffects/config/easyeffects`) MUST be symlinked to the central, chezmoi-tracked `~/.config/easyeffects` folder via setup scripts to ensure presets remain in sync.
63+
64+
## 11. KDE Panels, Greeters, and Settings
65+
- **KDE Panels & Applets**: Do NOT track the dynamic `plasma-org.kde.plasma.desktop-appletsrc` file as it contains coordinate layouts and unique IDs that break across screens. Instead, panels must be configured programmatically using the KDE Desktop Scripting API via `scripts/setup_plasma_panels.js`.
66+
- **kscreenlockerrc**: Static screen lock settings (disabling auto-lock, setting solid black background) are tracked directly as a private chezmoi file (`dot_config/private_kscreenlockerrc`).
67+
- **SDDM Greeter Theme Sync**: Do NOT track `/etc/sddm.conf` directly. Instead, customize the login screen programmatically during bootstrapping by writing synchronized cursor/font settings to `/etc/sddm.conf.d/kde_settings.conf`.
68+
69+
## 12. Steam Client and Gaming Optimizations
70+
- **Client Configuration**: Do NOT track Steam's `config.vdf` file directly as it contains personal credentials and active download history logs.
71+
- **Download Speed Fixes**: Automatically write the HTTP2 and connection optimizations (`steam_dev.cfg`) to `~/.local/share/Steam/steam_dev.cfg` during bootstrapping.
72+
- **Btrfs No-CoW**: Always disable Copy-on-Write (`chattr +C`) on Steam directories to prevent database fragmentation and gaming stutters.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>launchOnLogin</key>
6+
<true/>
7+
</dict>
8+
</plist>

bootstrap.sh

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,55 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
4949
export SUI_SUDO="sudo -A"
5050
trap 'rm -f "$SUDO_ASKPASS"' EXIT
5151
else
52-
export SUI_SUDO="pkexec"
52+
if command -v pkexec &> /dev/null; then
53+
export SUI_SUDO="pkexec"
54+
else
55+
export SUI_SUDO="sudo"
56+
fi
57+
fi
58+
59+
# Ensure basic prerequisites are installed on Fedora/Linux
60+
if [[ "$OSTYPE" != "darwin"* ]] && command -v dnf &> /dev/null; then
61+
MISSING_PREREQS=()
62+
for cmd in curl tar unzip git pkexec; do
63+
if ! command -v "$cmd" &>/dev/null; then
64+
pkg="$cmd"
65+
if [[ "$cmd" == "pkexec" ]]; then pkg="polkit"; fi
66+
MISSING_PREREQS+=("$pkg")
67+
fi
68+
done
69+
70+
if [ ${#MISSING_PREREQS[@]} -ne 0 ]; then
71+
echo "Installing missing prerequisites: ${MISSING_PREREQS[*]}"
72+
if [ "$EUID" -eq 0 ]; then
73+
dnf install -y "${MISSING_PREREQS[@]}"
74+
else
75+
sudo dnf install -y "${MISSING_PREREQS[@]}"
76+
fi
77+
fi
5378
fi
5479

5580
# Terminal Candy: install gum
5681
if ! command -v gum &> /dev/null; then
5782
echo "Installing gum for terminal UI..."
5883
GUM_VERSION="0.14.3"
84+
ARCH=$(uname -m)
5985
if [[ "$OSTYPE" == "darwin"* ]]; then
60-
curl -sL "https://github.com/charmbracelet/gum/releases/download/v${GUM_VERSION}/gum_${GUM_VERSION}_Darwin_arm64.tar.gz" | tar xz -C /tmp
86+
GUM_ARCH="Darwin_x86_64"
87+
if [[ "$ARCH" == "arm64" ]]; then
88+
GUM_ARCH="Darwin_arm64"
89+
fi
90+
curl -sL "https://github.com/charmbracelet/gum/releases/download/v${GUM_VERSION}/gum_${GUM_VERSION}_${GUM_ARCH}.tar.gz" | tar xz -C /tmp
6191
mkdir -p "$HOME/.local/bin"
62-
mv /tmp/gum_${GUM_VERSION}_Darwin_arm64/gum "$HOME/.local/bin/gum"
92+
mv "/tmp/gum_${GUM_VERSION}_${GUM_ARCH}/gum" "$HOME/.local/bin/gum"
6393
else
64-
curl -sL "https://github.com/charmbracelet/gum/releases/download/v${GUM_VERSION}/gum_${GUM_VERSION}_linux_x86_64.tar.gz" | tar xz -C /tmp
94+
GUM_ARCH="linux_x86_64"
95+
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
96+
GUM_ARCH="linux_arm64"
97+
fi
98+
curl -sL "https://github.com/charmbracelet/gum/releases/download/v${GUM_VERSION}/gum_${GUM_VERSION}_${GUM_ARCH}.tar.gz" | tar xz -C /tmp
6599
mkdir -p "$HOME/.local/bin"
66-
mv /tmp/gum_${GUM_VERSION}_linux_x86_64/gum "$HOME/.local/bin/gum"
100+
mv "/tmp/gum_${GUM_VERSION}_${GUM_ARCH}/gum" "$HOME/.local/bin/gum"
67101
fi
68102
export PATH="$HOME/.local/bin:$PATH"
69103
fi
@@ -120,8 +154,8 @@ echo ""
120154
gum style --border normal --margin "1" --padding "1" --border-foreground 212 "Starting Dotfiles Bootstrap (${PROFILE} profile)"
121155

122156
# Shell History Migration (Bash -> Zsh)
123-
if [[ -n "$BASH_VERSION" ]] || [[ -f "$HOME/.bash_history" ]]; then
124-
run_step "Migrating Bash history to Zsh format" bash -c 'if [[ -f "$HOME/.bash_history" ]]; then cat "$HOME/.bash_history" | while read -r line; do echo ": $(date +%s):0;$line"; done >> "$HOME/.zsh_history"; fi'
157+
if [[ -f "$HOME/.bash_history" ]]; then
158+
run_step "Migrating Bash history to Zsh format" bash -c 'cat "$HOME/.bash_history" | while read -r line; do echo ": $(date +%s):0;$line"; done >> "$HOME/.zsh_history" && mv "$HOME/.bash_history" "$HOME/.bash_history.migrated"'
125159
fi
126160

127161
# 0. Update System Packages
@@ -142,10 +176,14 @@ if [[ $AUTO_YES -eq 1 ]] || gum confirm "Setup YubiKey for passwordless sudo now
142176
run_step_sudo "Enabling Smartcard Daemon (pcscd)" systemctl enable --now pcscd.socket 2>/dev/null || true
143177

144178
if [ ! -f "$HOME/.config/Yubico/u2f_keys" ] && command -v pamu2fcfg &> /dev/null; then
145-
echo ""
146-
gum style --foreground 220 "🔑 Please enter your YubiKey PIN (if prompted) and then touch your YubiKey..."
147-
mkdir -p "$HOME/.config/Yubico"
148-
pamu2fcfg > "$HOME/.config/Yubico/u2f_keys" || true
179+
if [[ $DRY_RUN -eq 1 ]]; then
180+
echo "[DRY-RUN] Touch YubiKey and write key map to $HOME/.config/Yubico/u2f_keys"
181+
else
182+
echo ""
183+
gum style --foreground 220 "🔑 Please enter your YubiKey PIN (if prompted) and then touch your YubiKey..."
184+
mkdir -p "$HOME/.config/Yubico"
185+
pamu2fcfg > "$HOME/.config/Yubico/u2f_keys" || true
186+
fi
149187
fi
150188

151189
run_step_sudo "Configuring PAM for YubiKey" bash -c "
@@ -181,15 +219,27 @@ fi
181219

182220
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
183221

184-
run_step "Linking Chezmoi to $REPO_DIR" bash -c "mkdir -p '$HOME/.config/chezmoi' && echo 'sourceDir = \"$REPO_DIR\"' > '$HOME/.config/chezmoi/chezmoi.toml'"
222+
run_step "Linking Chezmoi to $REPO_DIR" bash -c "
223+
mkdir -p '\$HOME/.config/chezmoi'
224+
if [ -f '\$HOME/.config/chezmoi/chezmoi.toml' ]; then
225+
if ! grep -q 'sourceDir' '\$HOME/.config/chezmoi/chezmoi.toml'; then
226+
echo 'sourceDir = \"$REPO_DIR\"' >> '\$HOME/.config/chezmoi/chezmoi.toml'
227+
fi
228+
else
229+
echo 'sourceDir = \"$REPO_DIR\"' > '\$HOME/.config/chezmoi/chezmoi.toml'
230+
fi"
185231

186232
# Apply dotfiles (this automatically triggers run_once_setup scripts)
187233
if [[ $AUTO_YES -eq 1 ]] || gum confirm "Apply dotfiles and overwrite local configurations?"; then
188234
echo ""
189235
gum style --foreground 212 "Applying dotfiles and running OS-specific setups..."
190236
# We do not use gum spin here because OS setups (dnf/brew) take a long time
191-
# and provide their own important interactive output/progress bars.
192-
chezmoi apply --force
237+
# and provide their own interactive output/progress bars.
238+
if [[ $DRY_RUN -eq 1 ]]; then
239+
chezmoi apply --force --dry-run
240+
else
241+
chezmoi apply --force
242+
fi
193243
gum style --foreground 46 "✔ Dotfiles applied successfully!"
194244
fi
195245

dot_config/environment.d/10-nvidia-wayland.conf

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# NVIDIA Shader Cache optimizations for gaming
2+
__GL_SHADER_DISK_CACHE_SIZE=10737418240
3+
__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1
4+
5+
# NVIDIA VA-API hardware video acceleration configuration
6+
NVD_BACKEND=direct

dot_config/environment.d/20-nvidia-shader-cache.conf

Lines changed: 0 additions & 2 deletions
This file was deleted.

dot_config/kwinrc.tmpl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ RefreshRate=240
1717
[Plugins]
1818
applicationswitcherEnabled=true
1919
highlightwindowEnabled=false
20-
toshy-dbus-notifyactivewindowEnabled=true
2120
wobblywindowsEnabled=false
2221
poloniumEnabled=false
2322

dot_config/mimeapps.list

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
[Added Associations]
2+
text/plain=dev.zed.Zed.desktop;
3+
video/mp4=mpv.desktop;
4+
video/x-matroska=mpv.desktop;
5+
video/webm=mpv.desktop;
6+
video/quicktime=mpv.desktop;
7+
application/pdf=org.gnome.Evince.desktop;
8+
image/png=com.interversehq.qView.desktop;
9+
image/jpeg=com.interversehq.qView.desktop;
10+
11+
[Default Applications]
12+
# Web
13+
text/html=google-chrome.desktop
14+
x-scheme-handler/http=google-chrome.desktop
15+
x-scheme-handler/https=google-chrome.desktop
16+
x-scheme-handler/about=google-chrome.desktop
17+
x-scheme-handler/unknown=google-chrome.desktop
18+
19+
# Folders
20+
inode/directory=org.kde.dolphin.desktop
21+
22+
# Text & Code
23+
text/plain=dev.zed.Zed.desktop
24+
text/markdown=dev.zed.Zed.desktop
25+
application/json=dev.zed.Zed.desktop
26+
application/xml=dev.zed.Zed.desktop
27+
text/xml=dev.zed.Zed.desktop
28+
text/yaml=dev.zed.Zed.desktop
29+
application/x-yaml=dev.zed.Zed.desktop
30+
text/x-python=dev.zed.Zed.desktop
31+
text/x-shellscript=dev.zed.Zed.desktop
32+
text/x-csrc=dev.zed.Zed.desktop
33+
text/x-chdr=dev.zed.Zed.desktop
34+
text/x-c++src=dev.zed.Zed.desktop
35+
text/x-c++hdr=dev.zed.Zed.desktop
36+
text/javascript=dev.zed.Zed.desktop
37+
38+
# Videos (MPV)
39+
video/mp4=mpv.desktop
40+
video/x-matroska=mpv.desktop
41+
video/webm=mpv.desktop
42+
video/quicktime=mpv.desktop
43+
video/mpeg=mpv.desktop
44+
video/x-msvideo=mpv.desktop
45+
video/ogg=mpv.desktop
46+
video/3gpp=mpv.desktop
47+
video/x-flv=mpv.desktop
48+
49+
# Audios (MPV)
50+
audio/mpeg=mpv.desktop
51+
audio/flac=mpv.desktop
52+
audio/ogg=mpv.desktop
53+
audio/x-wav=mpv.desktop
54+
audio/aac=mpv.desktop
55+
audio/m4a=mpv.desktop
56+
audio/x-m4a=mpv.desktop
57+
58+
# Images (qView)
59+
image/png=com.interversehq.qView.desktop
60+
image/jpeg=com.interversehq.qView.desktop
61+
image/gif=com.interversehq.qView.desktop
62+
image/webp=com.interversehq.qView.desktop
63+
image/svg+xml=com.interversehq.qView.desktop
64+
image/bmp=com.interversehq.qView.desktop
65+
image/tiff=com.interversehq.qView.desktop
66+
67+
# Documents & PDFs (Evince)
68+
application/pdf=org.gnome.Evince.desktop
69+
70+
# Custom URI Handlers
71+
x-scheme-handler/antigravity=antigravity.desktop
72+
x-scheme-handler/bitwarden=bitwarden.desktop
73+
x-scheme-handler/com.todoist=todoist.desktop
74+
x-scheme-handler/todoist=todoist.desktop

dot_config/mpv/script-opts/uosc.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ progress_line_width=20
8484
# fullscreen = cycle:crop_free:fullscreen:no/yes=fullscreen_exit!?Fullscreen
8585
# loop-playlist = cycle:repeat:loop-playlist:no/inf!?Loop playlist
8686
# toggle:{icon}:{prop} = cycle:{icon}:{prop}:no/yes!
87-
controls=menu,gap,<video,audio>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,gap,space,<video,audio>speed,space,shuffle,loop-playlist,loop-file,gap,prev,items,next,gap,fullscreen
87+
controls=menu,gap,<video,audio>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,gap,space,<video,audio>speed,space,shuffle,loop-playlist,loop-file,gap,prev,items,next,gap,cycle:volume_up:mute:no/yes=volume_off!,gap,fullscreen
8888
controls_size=32
8989
controls_margin=8
9090
controls_spacing=2

0 commit comments

Comments
 (0)