A visual Alt+Tab window switcher for Hyprland, written in Rust. It renders a fullscreen Wayland layer-shell overlay showing all open windows across all workspaces, with keyboard navigation to quickly select and focus any window.
- Visual overlay showing all open windows with icons, titles, and workspace badges
- Keyboard navigation: Tab/Arrow keys to cycle, Enter to confirm, Escape to dismiss
- Standard Alt+Tab behavior: releasing Alt confirms the selection
- Reverse cycling with Shift+Tab or
--reverseflag - Automatic icon resolution from XDG
.desktopfiles with theme support - Exec-on-keybind design: zero resource usage when inactive
- IPC-based fast cycling: subsequent Alt+Tab presses cycle the existing overlay instead of restarting
- PID file deduplication to prevent stacking overlays
- Horizontal scrollable card layout with accent-highlighted selection
- Automatic focus when only one window is open
- Hyprland (Wayland compositor)
- Rust toolchain (1.85+ for edition 2024)
- System dependencies for Wayland/layer-shell rendering
sudo pacman -S wayland wayland-protocols libxkbcommonsudo dnf install wayland-devel wayland-protocols-devel libxkbcommon-develsudo apt install libwayland-dev wayland-protocols libxkbcommon-devgit clone https://github.com/nandomoreirame/hypr-switcher.git cd hypr-switcher cargo build --releaseThe binary will be at target/release/hypr-switcher.
cp target/release/hypr-switcher ~/.local/bin/Make sure ~/.local/bin is in your $PATH.
Add the following to your Hyprland config (e.g. ~/.config/hypr/bindings.conf or ~/.config/hypr/hyprland.conf):
# Unbind default Alt+Tab if previously set unbind = ALT, TAB unbind = ALT SHIFT, TAB # Bind hypr-switcher bindd = ALT, TAB, Window switcher, exec, hypr-switcher bindd = ALT SHIFT, TAB, Window switcher (reverse), exec, hypr-switcher --reverseAfter editing, reload Hyprland:
hyprctl reloadOnce configured, press Alt+Tab to open the switcher overlay. The overlay shows all open windows as horizontal cards with:
- Application icon (resolved from your icon theme)
- Application class name
- Window title (truncated if long)
- Workspace badge
| Key | Action |
|---|---|
Tab / Arrow Right | Select next window |
Shift+Tab / Arrow Left | Select previous window |
Enter | Focus selected window and close overlay |
Escape | Dismiss overlay without changing focus |
Release Alt | Focus selected window and close overlay |
- First press: The overlay opens with the previously focused window pre-selected (index 1), matching standard Alt+Tab behavior.
- Subsequent presses: If the overlay is already open, additional Alt+Tab presses cycle through windows via IPC without restarting the overlay.
- Single window: If only one window is open, it is auto-focused immediately without showing the overlay.
- No windows: The overlay shows an empty state message and dismisses on any key press.
hypr-switcher # Open switcher, cycle forward hypr-switcher --reverse # Open switcher, cycle backward src/ ├── main.rs # Entry point: PID management, IPC listener, iced launch ├── app.rs # Iced application state, update loop, keyboard handling ├── hyprland/ │ ├── mod.rs │ ├── ipc.rs # Hyprland Unix socket IPC (get_clients, focus_window) │ └── types.rs # HyprClient, WindowEntry structs with serde ├── icons/ │ ├── mod.rs │ └── resolver.rs # XDG icon resolution with theme + pixmaps fallback └── ui/ ├── mod.rs ├── style.rs # Design tokens (colors, dimensions) └── window_list.rs # Window card rendering (icon + class + title + badge) | Component | Choice |
|---|---|
| Language | Rust (edition 2024) |
| UI Framework | iced 0.14 + iced_layershell 0.15 |
| Async Runtime | tokio (for Unix socket IPC) |
| Serialization | serde + serde_json |
| Icons | freedesktop-icons + XDG .desktop file parsing |
| Logging | tracing + tracing-subscriber |
cargo buildcargo testRUST_LOG=debug cargo runcargo test hyprland:: cargo test icons:: cargo test app::By default, hypr-switcher uses the Yaru-purple icon theme. To change it, modify the theme name in src/main.rs:
let mut icon_resolver = IconResolver::new(Some("Your-Theme-Name".to_string()));The icon resolution follows this fallback chain:
- XDG icon theme lookup (configured theme)
- Hicolor fallback (default freedesktop theme)
/usr/share/pixmaps/directory- No icon (card displays without icon)
Contributions are welcome! See CONTRIBUTING.md for guidelines on how to get started.
