A Rust-based companion daemon for the Hyprland window manager. Hyprhelp extends Hyprland with features that aren't natively supported like session persistence, dynamic window rules, and workspace automation, driven by a fast async IPC layer built on Hyprland's Unix socket API.
Save and restore your entire workspace layout. Hyprhelp captures every open window,its position, size, workspace, and floating state, serializes it to JSON. On restore it relaunches each app and places it back exactly where it was, using polling-based window detection to reliably identify newly opened windows without race conditions.
Define rules in a TOML config file that fire automatically whenever a window opens. Match on window class, title, workspace, monitor, floating state, or even time of day. Actions include moving windows to workspaces, toggling fullscreen, floating, focusing, closing, pinning, and more. The rules engine hot-reloads your config the moment you save it.
A clean async abstraction over Hyprland's Unix sockets. Every feature in hyprhelp is built on top of this layer, which handles command dispatch, JSON response parsing, and real-time event streaming via a broadcast channel.
- Hyprland (any recent version)
- Rust toolchain (
rustuprecommended) cargo
git clone https://github.com/theripper-1920/hyprhelp.git
cd hyprhelp
cargo build --releaseThen copy the binary to somewhere on your PATH:
cp target/release/hyprhelp ~/.local/bin/hyprhelp ipc clients # list all open windows as JSON
hyprhelp ipc workspaces # list all workspaces
hyprhelp ipc monitors # list all monitors
hyprhelp ipc activewindow # show the currently focused windowhyprhelp monitor # stream live Hyprland events to stdouthyprhelp send "dispatch workspace 2"hyprhelp session save <name> # save current layout
hyprhelp session restore <name> # restore a saved layout
hyprhelp session list # list all saved sessions
hyprhelp session delete <name> # delete a saved sessionSessions are stored as JSON files at ~/.local/share/hyprhelp/sessions/.
hyprhelp daemon start # start the rules engine daemon
hyprhelp rules list # print all loaded rules
hyprhelp rules reload # force reload rules config
hyprhelp rules test <class> # test which rules match a window classRules are defined at ~/.config/hyprhelp/rules.toml. The file is created automatically on first run.
# move firefox to workspace 2
[[rules]]
actions = ["move_to_workspace 2"]
enabled = true
[rules.match]
class = "org.mozilla.firefox"
# move discord to workspace 4
[[rules]]
actions = ["move_to_workspace 4"]
enabled = true
[rules.match]
class = "discord"
# fullscreen YouTube in firefox
[[rules]]
actions = ["move_to_workspace 3", "fullscreen"]
enabled = true
[rules.match]
class = "org.mozilla.firefox"
title_contains = "YouTube"
# time-based rule — move steam to workspace 5 after 6pm
[[rules]]
actions = ["move_to_workspace 5", "float"]
enabled = true
[rules.match]
class = "steam"
time_after = "18:00"
time_before = "23:00"| Field | Type | Description |
|---|---|---|
class |
string | Exact window class match (case insensitive) |
class_contains |
string | Partial class match |
title |
string | Exact window title match |
title_contains |
string | Partial title match |
workspace |
string | Workspace id or name |
monitor |
number | Monitor index |
is_floating |
bool | Floating state |
time_after |
string | Match after HH:MM |
time_before |
string | Match before HH:MM |
| Action | Description |
|---|---|
move_to_workspace <id> |
Move window to workspace silently |
workspace <id> |
Switch to workspace |
fullscreen |
Maximize window |
fullscreen_real |
True fullscreen |
fullscreen_fake |
Fake fullscreen |
float |
Toggle floating |
focus |
Focus the window |
close |
Close the window |
pin |
Pin window across workspaces |
minimize |
Send to special:minimized |
move_to_monitor <id> |
Move to a different monitor |
set_size <w> <h> |
Resize window in pixels |
set_position <x> <y> |
Move window in pixels |
To start the rules engine automatically with Hyprland, add this to your hyprland.conf:
exec-once = hyprhelp daemon start
- Apps that manage their own session state (VS Code, Firefox) may reopen their last window position and ignore hyprhelp's move commands.
- Apps where the window class doesn't match the binary name need a launch override.
src/
├── main.rs
├── ipc/ ← Hyprland IPC layer
│ ├── mod.rs ← HyprlandIpc public facade
│ ├── socket.rs ← Unix socket communication
│ ├── command.rs ← typed command builders
│ ├── event_listener.rs ← real-time event streaming
│ └── types.rs ← Hyprland data types
├── features/
│ ├── mod.rs
│ ├── session/ ← session save and restore
│ │ ├── capture.rs
│ │ ├── store.rs
│ │ ├── restore.rs
│ │ └── mod.rs
│ └── rules/ ← dynamic rules engine
│ ├── config.rs
│ ├── condition.rs
│ ├── action.rs
│ ├── mod.rs
└── cli/ ← clap CLI definitions and handlers
├── args.rs
├── commands.rs
└── mod.rs