85 lines
3.4 KiB
Markdown
85 lines
3.4 KiB
Markdown
# Repository Guidelines
|
|
|
|
## Purpose and scope
|
|
|
|
`hypr-switcher` provides macOS-style application switching and hiding on
|
|
Hyprland without compositor patches. Prefer stock Hyprland IPC operations over
|
|
changes to the Hyprland fork. A compositor change should only be considered
|
|
when the required operation cannot be expressed through the command or event
|
|
sockets.
|
|
|
|
## Project structure
|
|
|
|
- `src/main.rs`: daemon lifecycle, local command socket, switch sessions, GTK
|
|
layer-shell HUD, and keyboard handling.
|
|
- `src/ipc.rs`: Hyprland command/event sockets and window operations.
|
|
- `src/model.rs`: client data, application grouping, address normalization, and
|
|
focus history.
|
|
- `src/desktop.rs`: XDG desktop-file metadata and icon lookup.
|
|
- `flake.nix`: standalone Nix package, app, checks, and development shell.
|
|
- `../hyprland.conf`: source configuration integration. The live config may be
|
|
deployed from another checkout; verify it before editing or reloading.
|
|
|
|
Add focused modules under `src/` rather than allowing `main.rs` to absorb
|
|
unrelated parsing or model logic.
|
|
|
|
## Behavioral invariants
|
|
|
|
- The process must remain a daemon. A one-shot switcher cannot retain a useful
|
|
MRU history between invocations.
|
|
- Group applications exactly as `Client::app_key` does: current class, then
|
|
initial class, then title, then address.
|
|
- Freeze normal MRU updates while a HUD session is active. Preview focus events
|
|
must not mutate the ordering captured at the start of that session.
|
|
- Keep application and same-application window cycle lists stable for the
|
|
duration of a cycle. Re-sorting after each preview causes two-window
|
|
oscillation instead of traversal.
|
|
- A selected application raises all of its windows, with the MRU representative
|
|
raised and focused last.
|
|
- The HUD owns an exclusive layer-shell keyboard grab. Release and hide it
|
|
before final focus, retaining the short delay in `Switcher::finish`; removing
|
|
that delay produces raised but unfocused windows.
|
|
- Hidden applications live in `ipc::HIDDEN_WORKSPACE`, are appended after
|
|
visible applications, and are not unhidden merely by previewing them. Restore
|
|
them only when the selection is committed.
|
|
- Hidden state must remain discoverable from Hyprland client metadata after a
|
|
daemon restart; do not make it depend solely on in-memory state.
|
|
|
|
## Build and validation
|
|
|
|
Before handing off changes, run:
|
|
|
|
```sh
|
|
cargo fmt --check
|
|
cargo test
|
|
cargo clippy --workspace --all-targets -- -D warnings
|
|
cargo build --release
|
|
nix flake check
|
|
```
|
|
|
|
Install a tested build with:
|
|
|
|
```sh
|
|
cargo install --path . --root ~/.local --force
|
|
```
|
|
|
|
After installation, restart the existing daemon. For configuration changes,
|
|
validate and reload the actual active Hyprland config, then inspect live binds
|
|
and `hyprctl configerrors`.
|
|
|
|
For runtime testing, use a disposable window/class rather than moving or
|
|
hiding the user's real applications. Confirm layer presence through
|
|
`hyprctl layers`, focus through `hyprctl activewindow`, and hidden placement
|
|
through `hyprctl clients`.
|
|
|
|
## Style and tests
|
|
|
|
Use Rust 2021 idioms and standard `rustfmt`. Keep IPC errors contextual and log
|
|
recoverable runtime failures without crashing the daemon. Add unit tests beside
|
|
pure parsing, grouping, and ordering logic. UI and compositor behavior require
|
|
proportional runtime checks in a live Hyprland session.
|
|
|
|
Preserve unrelated dirty changes in both configuration checkouts. Use
|
|
`readlink -f ~/.config/hypr/hyprland.conf` before assuming the workspace copy is
|
|
the active one.
|