initial commit
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user