- C 73.4%
- Shell 21.5%
- Makefile 3.8%
- Nix 1.3%
| assets | ||
| docs | ||
| protocol | ||
| scripts | ||
| src | ||
| tests | ||
| themes | ||
| .gitignore | ||
| AUTOCOLOR_GUIDE.txt | ||
| config.ini.example | ||
| flake.lock | ||
| flake.nix | ||
| Makefile | ||
| PKGBUILD | ||
| README.md | ||
| snappy-switcher-3.3.1-1-x86_64.pkg.tar.zst | ||
| snappy-switcher.service | ||
| snappy-switcher.spec | ||
⚠️ This is a fork of OpalAayan/snappy-switcher with one primary addition: Material You auto-theming. The switcher reads your live system palette from
quickshell/davinci-convertand hot-reloads colors the instant your wallpaper changes — no daemon restart needed. Everything else is upstream.
⚡ Snappy Switcher
A blazing-fast, animated Alt+Tab window switcher for Hyprland
The window switcher that actually understands your workflow.
✨ Why Snappy Switcher?
Snappy Switcher isn't just another window list—it's a context-aware window manager that thinks like you do:
| Feature | Description |
|---|---|
| Context Grouping | Automatically groups tiled windows by workspace + app class. Your 5 terminal windows become one clean card. |
| Sticky Mode | Configurable active-window focus retention. Press Alt+Tab to open without immediately losing focus. |
| 15 Themed Skins | Ships with Catppuccin, Dracula, Nord, Liquid Glass, Tokyo Night, and more. Full .ini customization. |
| Native Performance | Pure C with Wayland Layer Shell. No Electron. No lag. |
| Crash Recovery | Socket takeover protocol ensures seamless recovery if the daemon restarts. |
| Polished Visuals | Animated selection, drop shadows, rounded corners, and app badges—all Cairo-rendered. |
| SVG & Flatpak Support | Native SVG icon rendering and automatic Flatpak icon discovery. |
| Material You | (this fork) Set name = auto and the switcher reads your live system palette and hot-reloads on wallpaper change. |
🎨 Material You Auto-Theming (v3.3.0)
This is the primary reason this fork exists.
Snappy Switcher can read your Material You palette generated by quickshell (or any tool that writes material_colors.scss) and apply it as a live theme — automatically updating the moment your wallpaper changes, with no daemon restart.
How it works
- Source file:
~/.local/state/quickshell/user/generated/material_colors.scss - Color mapping:
$inversePrimary→ accent (better saturation than raw$primaryin dark mode),$background→ panel background,$surfaceContainer→ card fill,$onSurface→ text - Hot-reload: a Linux
inotifywatch on the SCSS directory triggers a live re-apply onIN_CLOSE_WRITE/IN_MOVED_TO— no restart needed - Implementation:
src/autocolor.c+src/autocolor.h, hooked intoconfig.cand the main event loop inmain.c - Tests: 21 unit tests in
tests/test_autocolor.c(make test-autocolor)
Enable it
One line in ~/.config/snappy-switcher/config.ini:
[theme]
name = auto
That's it. Change your wallpaper → Material You updates material_colors.scss → Snappy Switcher picks it up instantly.
Dependencies
| Package | Role |
|---|---|
quickshell (optional) |
Generates material_colors.scss from your wallpaper |
The auto mode gracefully falls back to the default theme if the SCSS file is missing.
How It Works
flowchart LR
subgraph Input[" "]
A["⌨ Alt+Tab"]
end
subgraph Daemon["🔧 Snappy Daemon"]
B[" Fetch Clients<br/>(Hyprland IPC)"]
C[" Sort by MRU<br/>(Most Recently Used)"]
D[" Context Aggregation<br/>(Group Tiled Windows)"]
end
subgraph Output[" "]
E[" Cairo Render"]
F[" Overlay Display"]
end
A --> B --> C --> D --> E --> F
style A fill:#89b4fa,stroke:#1e1e2e,color:#1e1e2e
style B fill:#a6e3a1,stroke:#1e1e2e,color:#1e1e2e
style C fill:#fab387,stroke:#1e1e2e,color:#1e1e2e
style D fill:#f9e2af,stroke:#1e1e2e,color:#1e1e2e
style E fill:#cba6f7,stroke:#1e1e2e,color:#1e1e2e
style F fill:#f38ba8,stroke:#1e1e2e,color:#1e1e2e
🔍 Context Mode in Action
graph TB
subgraph Before[" Raw Window List"]
W1["kitty<br/>workspace 1"]
W2["kitty<br/>workspace 1"]
W3["firefox<br/>workspace 2"]
W4["kitty<br/>workspace 1"]
W5["firefox<br/>floating"]
end
subgraph After["After Context Aggregation"]
G1["🔲 kitty × 3<br/>workspace 1"]
G2["🔲 firefox<br/>workspace 2"]
G3["🔳 firefox<br/>floating"]
end
Before -->|"Group Tiled<br/>Preserve Floating"| After
style G1 fill:#313244,stroke:#89b4fa,color:#cdd6f4
style G2 fill:#313244,stroke:#89b4fa,color:#cdd6f4
style G3 fill:#45475a,stroke:#f38ba8,color:#cdd6f4
💡 Floating windows are always shown individually~they're special!
📦 Installation
Arch Linux (AUR)
|
Using Yay |
Using Paru |
📦 Build from PKGBUILD
git clone https://github.com/OpalAayan/snappy-switcher.git
cd snappy-switcher
makepkg -si
📦 Other Linux Distributions (Fedora, etc.)
Install dependencies (Fedora/RHEL):
sudo dnf install wayland-devel cairo-devel pango-devel json-c-devel libxkbcommon-devel glib2-devel librsvg2-devel
Note: RPM packages are available for Fedora/RHEL. See the included
snappy-switcher.specfile for building viarpmbuildor Copr.
Nix / NixOS
|
Install with Flakes |
Run directly |
📦 Add to NixOS Configuration
# flake.nix
{
inputs.snappy-switcher.url = "github:OpalAayan/snappy-switcher";
}
# configuration.nix
environment.systemPackages = [
inputs.snappy-switcher.packages.${pkgs.system}.default
];
Manual Build
📋 Dependencies
| Package | Purpose |
|---|---|
wayland |
Core protocol |
cairo |
2D rendering |
pango |
Text layout |
json-c |
IPC parsing |
libxkbcommon |
Keyboard handling |
glib2 |
Utilities |
librsvg |
SVG icons (optional) |
Install dependencies (Arch):
sudo pacman -S wayland cairo pango json-c libxkbcommon glib2 librsvg
# Build
make
# Install system-wide
sudo make install
# Or install for current user only
make install-user
🚀 Quick Start
1️⃣ Setup Configuration
snappy-install-config
This copies themes and creates ~/.config/snappy-switcher/config.ini.
2️⃣ Add to Hyprland Config
Add these lines to ~/.config/hypr/hyprland.conf:
# Start the daemon on login
exec-once = snappy-switcher --daemon
# Keybindings
bind = ALT, Tab, exec, snappy-switcher next
bind = ALT SHIFT, Tab, exec, snappy-switcher prev
3️⃣ You're Done! 🎉
Press Alt + Tab to see it in action.
🎨 Theme Gallery
All 15 themes included out of the box. Just change one line in your config!
![]() Snappy Slate Default |
![]() Catppuccin Mocha |
![]() Catppuccin Latte |
![]() Catppuccin Frappé New in v3.0 |
![]() Tokyo Night |
![]() Nord |
![]() Nordic |
![]() Dracula |
![]() Gruvbox Dark |
![]() Rosé Pine |
![]() Cyberpunk |
![]() Grovestorm |
![]() Stormlight New in v3.0 |
![]() Liquid Glass White New in v3.0 |
![]() Liquid Glass Black New in v3.0 |
🎯 Change Theme
Edit ~/.config/snappy-switcher/config.ini:
[theme]
name = catppuccin-mocha.ini
⚙️ Configuration
🔧 Full Configuration Reference
# ~/.config/snappy-switcher/config.ini
[general]
# overview = Show all windows individually
# context = Group tiled windows by workspace + app class
mode = context
[theme]
name = snappy-slate.ini
border_width = 2
corner_radius = 12
[layout]
card_width = 160
card_height = 140
card_gap = 10
padding = 20
max_cols = 5
icon_size = 56
[icons]
theme = Tela-dracula
fallback = hicolor
show_letter_fallback = true
[font]
family = Sans
weight = Bold
title_size = 10
My Conf
[general]
mode = context
follow_monitor = true
show_workspace_badge = true
dismiss_modifier = alt
sticky_mode = false
[theme]
name = stormlight.ini
border_width = 2
corner_radius = 15
[layout]
card_width = 145
card_height = 135
card_gap = 10
padding = 10
max_cols = 5
icon_size = 57
icon_radius = 15
[icons]
theme = Tela-dracula
fallback = Tela-dracula
show_letter_fallback = true
[font]
family = FiraCode Nerd Font
weight = Bold
title_size = 10
icon_letter_size = 24
📘 Full Configuration Documentation →
Known Limitations
⚠️ Note on using SUPER as the dismiss modifier
If you set dismiss_modifier = super, native Arrow Key navigation (Left/Right/Up/Down) while the switcher is open may fail on certain compositors like Hyprland.
Why? Hyprland aggressively routes SUPER + Arrow keystrokes to its own internal global keybindings (like movefocus), preventing Snappy Switcher from receiving the input.
Workarounds:
- Navigate using the trigger key (e.g.,
Super + Tabrepeatedly). - Use
Super + Alt + Arrow Keysto bypass the compositor's interception. - Keep the default
dismiss_modifier = alt. (PRs welcome from any Wayland protocol wizards who know how to force Hyprland to yield these keys!)
🏗️ Architecture
flowchart TB
subgraph Client["Client Commands"]
CMD["snappy-switcher next/prev"]
end
subgraph Daemon["Daemon Process"]
SOCK["Unix Socket<br/>/tmp/snappy-switcher.sock"]
subgraph Core["Core Logic"]
HYP["hyprland.c<br/>IPC + Window Fetch"]
CFG["config.c<br/>INI Parsing"]
ICO["icons.c<br/>Theme Resolution"]
end
subgraph Render["Rendering"]
RND["render.c<br/>Cairo + Pango"]
INP["input.c<br/>Keyboard Events"]
end
WL["Wayland<br/>Layer Shell"]
end
subgraph External["External"]
HYP_IPC["Hyprland IPC"]
DISP["Display Server"]
end
CMD -->|"send command"| SOCK
SOCK --> HYP
HYP <-->|"j/clients"| HYP_IPC
CFG --> RND
ICO --> RND
HYP --> RND
RND --> WL
INP --> WL
WL <--> DISP
style SOCK fill:#89b4fa,stroke:#1e1e2e,color:#1e1e2e
style HYP fill:#a6e3a1,stroke:#1e1e2e,color:#1e1e2e
style RND fill:#cba6f7,stroke:#1e1e2e,color:#1e1e2e
style WL fill:#f9e2af,stroke:#1e1e2e,color:#1e1e2e
📁 Key Components
| File | Purpose |
|---|---|
main.c |
Daemon, event loop, socket server |
hyprland.c |
IPC client, window parsing, context aggregation |
render.c |
Cairo/Pango rendering, card drawing |
config.c |
INI parser, theme loading |
icons.c |
Icon theme resolution (XDG compliant) |
input.c |
Keyboard handling via libxkbcommon |
socket.c |
Unix socket IPC |
📘 Full Architecture Documentation →
🧪 Available Commands
| Command | Description |
|---|---|
snappy-switcher --daemon |
Start background daemon |
snappy-switcher next |
Cycle to next window |
snappy-switcher prev |
Cycle to previous window |
snappy-switcher toggle |
Show/hide switcher |
snappy-switcher hide |
Force hide overlay |
snappy-switcher select |
Confirm current selection |
snappy-switcher quit |
Stop the daemon |
🤝 Contributing
Contributions are welcome! Here's how to get started:
# Clone the repo
git clone https://github.com/OpalAayan/snappy-switcher.git
cd snappy-switcher
# Build
make
# Run tests
make test
# Clean build
make clean && make
# Run stress tests
./scripts/ultimate_stress_test.sh
Credits & Inspiration
This project was built with ❤️ for the Linux customization community.
| Project | Contribution |
|---|---|
| hyprshell | Massive inspiration for client parsing and layer-shell handling |
| Hyprland | The incredible compositor that makes this possible |
| Catppuccin | Beautiful color palettes used in themes |













