Files
hypr-switcher/README.md
T
2026-07-18 11:21:00 -07:00

108 lines
3.9 KiB
Markdown

# hypr-switcher
A macOS-style application switcher for Hyprland. It runs as a small GTK
layer-shell daemon, tracks focus through Hyprland's event socket, and exposes
commands for application and same-application window switching.
The application HUD groups windows by Hyprland `class`, orders applications and
their windows by most-recent focus, and resolves names and icons from installed
desktop files. Selecting an application raises all of its windows and focuses
its most-recent window.
This implementation uses only standard Hyprland IPC. It does not depend on the
custom `cycleapp` or `cycleappwindow` dispatchers.
## Behavior
- `Super+Tab` / `Super+Shift+Tab`: show the application HUD and move selection.
- Release `Super` or press `Enter`: accept the selection.
- `Escape`: cancel and restore the original application.
- `Super+grave` / `Super+Shift+grave`: cycle windows in the current application.
- `Super+H`: hide every window in the current application.
Hidden windows are moved silently to `special:hypr-switcher-hidden`. Their
applications remain visible, dimmed, at the end of the HUD. Selecting a hidden
application restores all of its windows to the current workspace and focuses
its most-recent window. The special workspace also lets the daemon rediscover
hidden applications after a restart.
The HUD displays applications from the current workspace plus hidden
applications. Normal application switching does not pull visible windows from
other workspaces.
## Requirements
- Hyprland with its command and event IPC sockets enabled (the default)
- GTK 4
- gtk4-layer-shell
- A working icon theme and desktop files under the standard XDG data paths
- Rust and Cargo to build from source
## Build and install
Run this from the directory containing this README:
```sh
cargo test
cargo clippy --workspace --all-targets -- -D warnings
cargo install --path . --root ~/.local --force
```
The binary is installed as `~/.local/bin/hypr-switcher`. The accompanying
`../hyprland.conf` starts the daemon and defines the bindings:
```ini
$switcher = ~/.local/bin/hypr-switcher
exec-once = $switcher daemon
layerrule = match:namespace ^(hypr-switcher)$, no_anim 1
bind = SUPER, Tab, exec, $switcher show
bind = SUPER SHIFT, Tab, exec, $switcher show-previous
bind = SUPER, grave, exec, $switcher window-next
bind = SUPER SHIFT, grave, exec, $switcher window-previous
bind = SUPER, H, exec, $switcher hide-current
```
After rebuilding, restart the daemon so the running process uses the new
binary. Reload Hyprland after changing bindings.
## Commands
```sh
hypr-switcher daemon
hypr-switcher show
hypr-switcher show-previous
hypr-switcher window-next
hypr-switcher window-previous
hypr-switcher hide-current
hypr-switcher cancel
```
Set `RUST_LOG=hypr_switcher=debug` on the daemon command for diagnostics.
## How it works
- `src/ipc.rs` talks directly to Hyprland's Unix sockets, listens for focus and
window events, raises/focuses windows, and moves hidden apps.
- `src/model.rs` owns address normalization, window metadata, application
grouping, and MRU ordering.
- `src/desktop.rs` resolves application names and icons from XDG desktop files.
- `src/main.rs` owns the daemon command socket, switch sessions, GTK HUD, and
keyboard handling.
The daemon freezes MRU updates while the HUD is previewing applications so its
own focus requests do not reorder the active switch session. Final focus is
sent shortly after the layer-shell HUD closes, allowing its exclusive keyboard
grab to be released first.
## Troubleshooting
- If commands report that the daemon is unavailable, start
`hypr-switcher daemon` or begin a new Hyprland session so `exec-once` runs.
- If the HUD works from the command line but not from `Super+Tab`, inspect live
bindings with `hyprctl binds` and verify which config is active with
`readlink -f ~/.config/hypr/hyprland.conf`.
- If an icon is missing, compare the Hyprland window `class` from
`hyprctl clients` with the desktop file name or its `StartupWMClass` value.