HyprSets is a TUI launcher for Hyprland worksets. Define a set of commands (and an optional tiled layout) once and launch them together. The app ships with a list view to pick or create worksets, plus a layout editor that mirrors Hyprland-style splits with mouse support.
- TUI home screen to run, duplicate, reorder, or delete worksets with mouse or keyboard.
- Tabbed workset list so you can group worksets, reorder tabs, and remember the last active tab.
- Layout editor that lets you split slots horizontally/vertically, tweak ratios, and edit slot commands in place.
- Launches worksets either sequentially or by walking the layout tree, waiting for windows to appear as it goes.
- Per-workset workspace targeting, including special workspaces (scratchpads), or stick to the current workspace by default.
- Prompts to close existing windows on the active workspace before launching to keep layouts clean.
- Config stored in TOML under
~/.config/hyprsets/hyprsets.toml(created automatically with a sample).
- Hyprland session with
hyprctlavailable onPATH. - Rust toolchain with edition 2024 support (e.g. Rust 1.80+).
python3only when runningscripts/package.sh.
From GitHub Releases (prebuilt artifacts):
- Quick install of the latest
x86_64-unknown-linux-gnubuild (aliasTARGET_ALIAS=linux-x86_64by default; setTARGETorTARGET_ALIASto override):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/agata/hyprsets/main/scripts/install-latest.sh)"Manual install: download hyprsets-<version>-<target>.tar.gz from the Releases page, extract it, then run the bundled install.sh. Checksum verification is optional via the matching .sha256 file.
From source:
git clone https://github.com/agata/hyprsets.git
cd hyprsets
cargo install --path .
# or
cargo build --releaseThe binary will live at ~/.cargo/bin/hyprsets (with cargo install) or target/release/hyprsets.
Packaged tarball:
./scripts/package.sh # builds, fmt + clippy by default
./scripts/package.sh --skip-checks # skip fmt/clippy
./scripts/package.sh --target <triple> # cross targetArtifacts are written under dist/ and include a desktop entry and install script.
If you installed from GitHub Releases, rerun the same install flow to overwrite the existing binary:
- Quick install (latest release):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/agata/hyprsets/main/scripts/install-latest.sh)"- Manual install: download the new
hyprsets-<version>-<target>.tar.gz, extract it, and run the bundledinstall.shagain.
If you installed from source:
git pull
cargo install --path . --force
# or rebuild locally
cargo build --releaseRebuilding or reinstalling replaces the existing binary in ~/.cargo/bin/hyprsets (or your target/release/hyprsets if you run it directly).
Config path: ~/.config/hyprsets/hyprsets.toml by default. Use --config <path> to override. First run writes a sample file if none exists.
Commands:
hyprsets— open the TUI home screen.hyprsets run <id>— run a workset directly (no UI).hyprsets edit <id>— open the layout editor for a workset.hyprsets version— print the HyprSets version.-v— print verbose launch logs (hyprctl operations, waits).
Launch behavior:
- If a layout is present, HyprSets traverses it, launching each slot and applying split ratios as windows appear.
- Slot/command launches wait 1s by default; set
wait_after_mson a layout slot to change the gap before the next slot (useful for slow-starting apps). - Without a layout, commands are executed sequentially with a short delay.
workspace(optional per workset) forces launch on a specific workspace name/ID orspecial[:name]; empty/missing uses the currently active workspace.- On launch it asks whether to close existing windows on the active workspace (skipped if none are present).
HYPRSETS_INITIAL_SPLITcan force the first split orientation when running layouts (horizontalorvertical; defaulthorizontal).
You can launch specific worksets automatically when Hyprland starts. Create worksets that target the workspaces you want, then call hyprsets run <id> from Hyprland's exec-once hooks.
Example worksets with explicit workspace targets:
[[workset]]
id = "ws-1"
name = "Project Atlas"
workspace = "1"
commands = [
'kitty --title "API Logs" sh -c "cd ~/projects/atlas && tail -f logs/dev.log"',
'brave --new-window https://status.example.com'
]
[[workset]]
id = "ws-scratch"
name = "Scratchpad Notes"
workspace = "special:scratchpad"
commands = [ 'kitty --title "Notes" nvim ~/notes/quick.md' ]Then add the launch commands to your Hyprland config ($HOME でユーザーごとのホームを参照できます):
exec-once = $HOME/.local/bin/hyprsets run ws-1
exec-once = $HOME/.local/bin/hyprsets run ws-scratch
This will start HyprSets as part of your session startup and place each workset on its defined workspace (including special workspaces) without opening the TUI.
Home:
Enterrun,eedit,nnew,cduplicate,ddelete (with confirm),Shift+J/Kreorder,aassign tab,ttab menu,q/Escquit.- Arrow keys or
j/kto move; mouse click/scroll supported; toolbar buttons are clickable.
Editor:
- Navigation:
Tab/Shift+Taborj/k/lto move between slots. - Split:
hfor horizontal,vorsfor vertical; drag split bars with the mouse. - Ratio:
+/-to adjust the active split. - Commands:
Enterorcto edit the current slot command. - Workset info:
eorF2to edit name/description. - Delete slot:
xord(confirmation shown);wswaps the selected slot with the next one. q/Escsaves and returns.
- Enable tabs with
version = 2(written automatically after adding a tab). Tabs are saved in[[tab]]entries; an implicitAlltab is always available. - Each workset belongs to at most one tab. Tab membership can be changed from the home screen (shortcut
a) or inside the workset editor. - Tab layout and selection:
- Tab order follows the config file; you can move tabs left/right via the tab menu (
t). - The last selected tab is persisted to
~/.config/hyprsets/state.toml. include_unassigned = truepulls in worksets that aren’t listed in any tab (ID-sorted).
- Tab order follows the config file; you can move tabs left/right via the tab menu (
- New worksets created from a user tab default to that tab; you can switch tab assignment in the creation dialog.
HyprSets writes a starter config automatically. A minimal example:
version = 1
[[workset]]
id = "sample"
name = "Sample Workset"
desc = "Code + Browser example"
workspace = "" # optional; empty means use the active workspace
# Used when no layout is defined (optional if you rely solely on the layout tree)
commands = [
'code -n "$HOME/ws/demo"',
'omarchy-launch-browser --new-window "https://example.com"'
]
# Layout tree takes precedence over the sequential commands above
[workset.layout]
type = "split"
direction = "horizontal" # or "vertical"
ratio = 1.2 # ratio between left/right (clamped for Hyprland)
[workset.layout.left]
type = "leaf"
slot_id = 1
command = 'code -n "$HOME/ws/demo"'
[workset.layout.right]
type = "leaf"
slot_id = 2
command = 'omarchy-launch-browser --new-window "https://example.com"'Notes:
workspaceaccepts a workspace name or numeric id. Usespecialorspecial:<name>to target scratchpad workspaces. Leaving it empty (or omitting it) keeps the "use current workspace" behavior.cwdandenvcan be set per workset or per slot; slot values override workset defaults.ratiois converted to Hyprland'ssplitratio exactand kept within a safe range.- Each layout slot can override the default 1s pause before the next slot with
wait_after_ms = <milliseconds>; omit it to keep the default. Use this for slow-to-launch apps so the next slot waits for the window to appear. You can set this from the layout editor's slot dialog (Enter/con a slot). - Slot
commandstrings are executed viahyprctl dispatch exec, so shell features should be quoted accordingly. - Each workset must have a unique
id;nameanddescare shown in the UI.
- Run
cargo fmt && cargo clippy -- -D warnings && cargo testbefore pushing. scripts/package.shperforms the same checks unless--skip-checksis used.
The project is now publicly available. Feedback and issues are welcome anytime.
