Back to skills
SkillHub ClubShip Full StackFull Stack

hyprland

Hyprland automation with hyprctl: create/close named workspaces, open a standard 3-window dev layout (Codex + shell + Neovim) for a project, and manage windows via hyprctl dispatch. Use when asked to manipulate Hyprland workspaces or windows, or to script Hyprland layouts.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
1
Hot score
77
Updated
March 20, 2026
Overall rating
C0.4
Composite score
0.4
Best-practice grade
B73.6

Install command

npx @skill-hub/cli install mainliufeng-dotfiles-hyprland

Repository

mainliufeng/dotfiles

Skill path: agents_config/personal/skills/hyprland

Hyprland automation with hyprctl: create/close named workspaces, open a standard 3-window dev layout (Codex + shell + Neovim) for a project, and manage windows via hyprctl dispatch. Use when asked to manipulate Hyprland workspaces or windows, or to script Hyprland layouts.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: mainliufeng.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install hyprland into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/mainliufeng/dotfiles before adding hyprland to shared team environments
  • Use hyprland for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: hyprland
description: "Hyprland automation with hyprctl: create/close named workspaces, open a standard 3-window dev layout (Codex + shell + Neovim) for a project, and manage windows via hyprctl dispatch. Use when asked to manipulate Hyprland workspaces or windows, or to script Hyprland layouts."
---

# Hyprland

## Quick start

- Create workspace: `scripts/hypr-ws-create.sh <name>`
- Close workspace(s): `scripts/hypr-ws-close.sh <name> [name...]`
- Open project layout: `scripts/hypr-ws-open-project.sh [project|path]`
- Open custom terminals: `scripts/hypr-ws-open-terms.sh <workspace> <dir> [Title::Command]...`
- Get instance signature: `scripts/hypr-instance.sh [--all]`
- Focus window by rule: `scripts/hypr-win-focus.sh --class REGEX --title REGEX`
- Move active window: `scripts/hypr-win-move.sh <workspace> [--follow]`
- Float & center: `scripts/hypr-win-float.sh --size 1300x800 --center`
- Resize active window: `scripts/hypr-win-resize.sh --exact 1300 800`
- Pick window (wofi): `scripts/hypr-win-pick.sh`
- List windows: `scripts/hypr-list-clients.sh`

## Workspace tasks

### Create a named workspace

Run `scripts/hypr-ws-create.sh <name>`.

### Close/delete a workspace

Run `scripts/hypr-ws-close.sh <name> [name...]`.

Behavior:
- Closes windows by address, then `killactive`, then SIGTERM/SIGKILL if needed.
- Switches to `HYPR_WS_FALLBACK` (default `1`) unless set to `none`.
- Removes workspace names from `~/.cache/hypr-launcher/workspaces.txt` if present.

### Open a 3-window dev layout

Run `scripts/hypr-ws-open-project.sh [project|path]`.

Defaults:
- Project roots: `~/Code/self` and `~/Code/rcrai`.
- Workspace name: repo basename.
- Term: `ghostty`.
- Codex args: `--dangerously-bypass-approvals-and-sandbox`.

Project resolution:
- `self/foo` -> `~/Code/self/foo`
- `rcrai/foo` -> `~/Code/rcrai/foo`
- `foo` -> search under both roots
- `/abs/path` -> use as-is

Env overrides:
- `HYPR_PROJECT_ROOTS` (colon-separated roots)
- `HYPR_WORKSPACE_NAME`
- `HYPR_WORKSPACE_TERM`
- `HYPR_WORKSPACE_NVIM_CMD`
- `HYPR_WORKSPACE_CODEX_BIN`
- `HYPR_WORKSPACE_CODEX_CMD`
- `HYPR_WORKSPACE_CODEX_ARGS`
- `HYPR_WORKSPACE_SHELL`
- `HYPR_WORKSPACE_SHELL_ARGS`
- `HYPR_WORKSPACE_PATH_PREFIX`

### Open custom terminal layout

Run `scripts/hypr-ws-open-terms.sh <workspace> <dir> [Title::Command]...`.

Examples:
- `scripts/hypr-ws-open-terms.sh notes ~/notes "Nvim::nvim" "Shell::zsh"`
- `HYPR_WS_TERMS="Codex::codex --dangerously-bypass-approvals-and-sandbox|Shell::zsh|Nvim::nvim" scripts/hypr-ws-open-terms.sh dev ~/Code/self/mobius`

Env overrides:
- `HYPR_WS_TERM`
- `HYPR_WS_SHELL`
- `HYPR_WS_SHELL_ARGS`
- `HYPR_WS_PATH_PREFIX`
- `HYPR_WS_TERMS`

## Window management

Use `hyprctl dispatch` for ad-hoc window actions. Add new scripts under `scripts/` when the action is repeatable.

Examples:
- Focus: `hyprctl dispatch focuswindow address:<addr>`
- Move: `hyprctl dispatch movetoworkspace name:<ws>`
- Resize: `hyprctl dispatch resizeactive exact 1300 800`

### Focus a window by rule

Run `scripts/hypr-win-focus.sh --class REGEX --title REGEX [--workspace NAME] [--icase] [--exec CMD]`.

### Move active window to workspace

Run `scripts/hypr-win-move.sh <workspace> [--follow]`.

### Toggle floating with size/center

Run `scripts/hypr-win-float.sh [--size WxH] [--center]`.

### Resize active window

Run `scripts/hypr-win-resize.sh --exact <width> <height>` or `--delta <dx> <dy>`.

### Center active window

Run `scripts/hypr-win-center.sh`.

### Pick a window (wofi)

Run `scripts/hypr-win-pick.sh` to select and focus.

### List clients

Run `scripts/hypr-list-clients.sh` to list `address`, `workspace`, `class`, `title`.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/hypr-ws-create.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

name="${1:-}"
if [[ -z "$name" ]]; then
  echo "usage: hypr-ws-create <workspace-name>" >&2
  exit 1
fi

hyprctl dispatch workspace "name:${name}"

```

### scripts/hypr-ws-close.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

if [[ "$#" -eq 0 ]]; then
  echo "usage: hypr-ws-close <workspace-name> [workspace-name...]" >&2
  exit 1
fi

python - "$@" <<'PY'
import json
import os
import signal
import subprocess
import sys
import time

targets = set(sys.argv[1:])
if not targets:
    raise SystemExit(1)

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
addresses = [
    c.get("address")
    for c in clients
    if c.get("workspace", {}).get("name") in targets
]

for addr in addresses:
    if not addr:
        continue
    subprocess.run(["hyprctl", "dispatch", "closewindow", f"address:{addr}"])

for addr in addresses:
    if not addr:
        continue
    subprocess.run(["hyprctl", "dispatch", "focuswindow", f"address:{addr}"])
    subprocess.run(["hyprctl", "dispatch", "killactive"])

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
pids = [
    c.get("pid")
    for c in clients
    if c.get("workspace", {}).get("name") in targets and c.get("pid")
]

for pid in pids:
    try:
        os.kill(pid, signal.SIGTERM)
    except ProcessLookupError:
        pass

time.sleep(0.2)

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
for c in clients:
    if c.get("workspace", {}).get("name") in targets and c.get("pid"):
        try:
            os.kill(c["pid"], signal.SIGKILL)
        except ProcessLookupError:
            pass

fallback = os.environ.get("HYPR_WS_FALLBACK", "1").strip()
if fallback and fallback.lower() not in {"none", "off", "false"}:
    subprocess.run(["hyprctl", "dispatch", "workspace", fallback])

history = os.path.expanduser("~/.cache/hypr-launcher/workspaces.txt")
if os.path.exists(history):
    with open(history, "r", encoding="utf-8") as fh:
        lines = [line.rstrip("\n") for line in fh]
    lines = [line for line in lines if line and line not in targets]
    with open(history, "w", encoding="utf-8") as fh:
        for line in lines:
            fh.write(line + "\n")
PY

```

### scripts/hypr-ws-open-project.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

if [[ -n "${HYPR_PROJECT_ROOTS:-}" ]]; then
  IFS=':' read -r -a project_roots <<<"$HYPR_PROJECT_ROOTS"
else
  project_roots=("$HOME/Code/self" "$HOME/Code/rcrai")
fi

project_arg="${1:-}"

if [[ -z "$project_arg" ]]; then
  if command -v wofi >/dev/null 2>&1; then
    project_arg="$(
      {
        for root in "${project_roots[@]}"; do
          [[ -d "$root" ]] || continue
          root_label="${root#$HOME/Code/}"
          if [[ "$root_label" == "$root" || -z "$root_label" ]]; then
            root_label="$(basename "$root")"
          fi
          find "$root" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null \
            | sort \
            | sed "s#^#${root_label}/#"
        done
      } | sort | wofi --show dmenu --prompt "Project"
    )"
  else
    echo "missing project name and wofi not installed" >&2
    exit 1
  fi
fi

if [[ -z "$project_arg" ]]; then
  exit 0
fi

repo=""
if [[ "$project_arg" = /* ]]; then
  repo="$project_arg"
elif [[ "$project_arg" == *"/"* ]]; then
  repo="$HOME/Code/$project_arg"
else
  for root in "${project_roots[@]}"; do
    if [[ -d "$root/$project_arg" ]]; then
      repo="$root/$project_arg"
      break
    fi
  done
fi

if [[ -z "$repo" ]]; then
  repo="${project_roots[0]}/${project_arg}"
fi

if [[ ! -d "$repo" ]]; then
  echo "repo not found: $repo" >&2
  exit 1
fi

workspace="${HYPR_WORKSPACE_NAME:-$(basename "$repo")}"
term="${HYPR_WORKSPACE_TERM:-ghostty}"
codex_cmd="${HYPR_WORKSPACE_CODEX_CMD:-codex}"
codex_bin="${HYPR_WORKSPACE_CODEX_BIN:-$HOME/.npm-global/bin/codex}"
nvim_cmd="${HYPR_WORKSPACE_NVIM_CMD:-nvim}"
codex_args="${HYPR_WORKSPACE_CODEX_ARGS:---dangerously-bypass-approvals-and-sandbox}"
shell="${HYPR_WORKSPACE_SHELL:-zsh}"
path_prefix="${HYPR_WORKSPACE_PATH_PREFIX:-$HOME/.npm-global/bin:$HOME/.opencode/bin}"

if [[ -z "${HYPR_WORKSPACE_SHELL_ARGS:-}" ]]; then
  if [[ "$shell" == "bash" ]]; then
    shell_args="-lc"
  else
    shell_args="-lic"
  fi
else
  shell_args="$HYPR_WORKSPACE_SHELL_ARGS"
fi

require_cmd() {
  local cmd="$1"
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "missing command: $cmd" >&2
    return 1
  fi
}

require_cmd hyprctl
require_cmd "$term"
require_cmd "$nvim_cmd"

hypr_instance() {
  if [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
    printf '%s\n' "$HYPRLAND_INSTANCE_SIGNATURE"
    return 0
  fi

  if [[ -x "$script_dir/hypr-instance.sh" ]]; then
    "$script_dir/hypr-instance.sh" 2>/dev/null || true
  fi
}

hypr() {
  local inst
  inst="$(hypr_instance || true)"
  if [[ -n "$inst" ]]; then
    hyprctl --instance "$inst" "$@"
  else
    hyprctl "$@"
  fi
}

spawn_term() {
  local title="$1"
  local snippet="$2"
  local repo_quoted shell_cmd path_prefix_quoted

  repo_quoted="$(printf %q "$repo")"
  path_prefix_quoted="$(printf %q "$path_prefix")"
  shell_cmd="export PATH=${path_prefix_quoted}:\$PATH; cd $repo_quoted; printf '\033]0;${title}\007'; ${snippet}"
  hypr dispatch exec "$term -e $shell $shell_args $(printf %q "$shell_cmd")"
}

hypr dispatch workspace "name:${workspace}"

spawn_term "${workspace} Codex" "if [ -x $(printf %q "$codex_bin") ]; then $(printf %q "$codex_bin") $codex_args; elif command -v $codex_cmd >/dev/null 2>&1; then $codex_cmd $codex_args; else echo 'codex not found'; fi; exec $shell"
sleep 0.2
spawn_term "${workspace} Shell" "exec $shell"
sleep 0.2
spawn_term "${workspace} Nvim" "exec $nvim_cmd"

```

### scripts/hypr-ws-open-terms.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

workspace="${1:-}"
repo="${2:-}"
shift 2 || true

if [[ -z "$workspace" || -z "$repo" ]]; then
  echo "usage: hypr-ws-open-terms <workspace> <dir> [Title::Command]..." >&2
  echo "or set HYPR_WS_TERMS=\"Title::Command|Title::Command\"" >&2
  exit 1
fi

if [[ ! -d "$repo" ]]; then
  echo "repo not found: $repo" >&2
  exit 1
fi

term="${HYPR_WS_TERM:-ghostty}"
shell="${HYPR_WS_SHELL:-zsh}"
path_prefix="${HYPR_WS_PATH_PREFIX:-$HOME/.npm-global/bin:$HOME/.opencode/bin}"

if [[ -z "${HYPR_WS_SHELL_ARGS:-}" ]]; then
  if [[ "$shell" == "bash" ]]; then
    shell_args="-lc"
  else
    shell_args="-lic"
  fi
else
  shell_args="$HYPR_WS_SHELL_ARGS"
fi

if [[ "$#" -gt 0 ]]; then
  terms=("$@")
elif [[ -n "${HYPR_WS_TERMS:-}" ]]; then
  IFS='|' read -r -a terms <<<"$HYPR_WS_TERMS"
else
  terms=("Shell::${shell}")
fi

require_cmd() {
  local cmd="$1"
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "missing command: $cmd" >&2
    return 1
  fi
}

require_cmd hyprctl
require_cmd "$term"

hypr_instance() {
  if [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
    printf '%s\n' "$HYPRLAND_INSTANCE_SIGNATURE"
    return 0
  fi

  if [[ -x "$script_dir/hypr-instance.sh" ]]; then
    "$script_dir/hypr-instance.sh" 2>/dev/null || true
  fi
}

hypr() {
  local inst
  inst="$(hypr_instance || true)"
  if [[ -n "$inst" ]]; then
    hyprctl --instance "$inst" "$@"
  else
    hyprctl "$@"
  fi
}

spawn_term() {
  local title="$1"
  local snippet="$2"
  local repo_quoted shell_cmd path_prefix_quoted

  repo_quoted="$(printf %q "$repo")"
  path_prefix_quoted="$(printf %q "$path_prefix")"
  shell_cmd="export PATH=${path_prefix_quoted}:\$PATH; cd $repo_quoted; printf '\033]0;${title}\007'; ${snippet}"
  hypr dispatch exec "$term -e $shell $shell_args $(printf %q "$shell_cmd")"
}

hypr dispatch workspace "name:${workspace}"

for item in "${terms[@]}"; do
  if [[ "$item" == *"::"* ]]; then
    title="${item%%::*}"
    cmd="${item#*::}"
  else
    title="$item"
    cmd="$item"
  fi
  if [[ -z "$cmd" ]]; then
    cmd="$shell"
  fi
  spawn_term "${workspace} ${title}" "$cmd"
  sleep 0.15
done

```

### scripts/hypr-instance.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

usage() {
  echo "usage: hypr-instance [--all]" >&2
}

all=0
case "${1:-}" in
  -a|--all)
    all=1
    shift
    ;;
  -h|--help)
    usage
    exit 0
    ;;
  "")
    ;;
  *)
    usage
    exit 1
    ;;
esac

declare -A seen=()
instances=()
preferred=""

add_instance() {
  local sig="$1"
  [[ -n "$sig" ]] || return 0
  if [[ -z "${seen[$sig]+x}" ]]; then
    seen["$sig"]=1
    instances+=("$sig")
  fi
}

has_socket() {
  local dir="$1"
  [[ -d "$dir" ]] || return 1
  local sock
  for sock in ".socket.sock" ".socket2.sock" "hyprland.sock" "hyprland.sock2"; do
    if [[ -S "$dir/$sock" ]]; then
      return 0
    fi
  done
  return 1
}

socket_mtime() {
  local dir="$1"
  local sock
  for sock in ".socket.sock" ".socket2.sock" "hyprland.sock" "hyprland.sock2"; do
    if [[ -S "$dir/$sock" ]]; then
      stat -c %Y "$dir/$sock" 2>/dev/null || printf '0\n'
      return 0
    fi
  done
  printf '0\n'
}

hypr_root="/tmp/hypr"
if [[ -n "${XDG_RUNTIME_DIR:-}" && -d "$XDG_RUNTIME_DIR/hypr" ]]; then
  hypr_root="$XDG_RUNTIME_DIR/hypr"
fi
if [[ -L "$hypr_root" ]]; then
  hypr_root="$(readlink -f "$hypr_root" 2>/dev/null || echo "$hypr_root")"
fi

if [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
  if has_socket "$hypr_root/$HYPRLAND_INSTANCE_SIGNATURE"; then
    if [[ "$all" -eq 0 ]]; then
      printf '%s\n' "$HYPRLAND_INSTANCE_SIGNATURE"
      exit 0
    fi
  fi
  add_instance "$HYPRLAND_INSTANCE_SIGNATURE"
fi

if command -v pgrep >/dev/null 2>&1; then
  while IFS= read -r pid; do
    env_file="/proc/$pid/environ"
    [[ -r "$env_file" ]] || continue
    if ! env_dump="$(tr '\0' '\n' < "$env_file" 2>/dev/null)"; then
      continue
    fi
    sig="$(printf '%s\n' "$env_dump" | awk -F= '$1=="HYPRLAND_INSTANCE_SIGNATURE"{print $2; exit}')"
    [[ -n "$sig" ]] || continue
    add_instance "$sig"
    if [[ -n "${WAYLAND_DISPLAY:-}" && -z "$preferred" ]]; then
      wd="$(printf '%s\n' "$env_dump" | awk -F= '$1=="WAYLAND_DISPLAY"{print $2; exit}')"
      if [[ -n "$wd" && "$wd" == "$WAYLAND_DISPLAY" ]]; then
        preferred="$sig"
      fi
    fi
  done < <(pgrep -x Hyprland 2>/dev/null || pgrep -f '[H]yprland' 2>/dev/null || true)
fi

if [[ -d "$hypr_root" ]]; then
  while IFS= read -r dir; do
    if has_socket "$dir"; then
      add_instance "$(basename "$dir")"
    fi
  done < <(find -L "$hypr_root" -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
fi

if [[ "$all" -eq 1 ]]; then
  if [[ "${#instances[@]}" -eq 0 ]]; then
    exit 1
  fi
  printf '%s\n' "${instances[@]}"
  exit 0
fi

if [[ -n "$preferred" ]]; then
  printf '%s\n' "$preferred"
  exit 0
fi

if [[ "${#instances[@]}" -eq 0 ]]; then
  exit 1
fi

if [[ "${#instances[@]}" -eq 1 ]]; then
  printf '%s\n' "${instances[0]}"
  exit 0
fi

latest_sig=""
latest_mtime=0
for sig in "${instances[@]}"; do
  mtime="$(socket_mtime "$hypr_root/$sig")"
  if [[ "$mtime" -gt "$latest_mtime" ]]; then
    latest_mtime="$mtime"
    latest_sig="$sig"
  fi
done

if [[ -n "$latest_sig" ]]; then
  printf '%s\n' "$latest_sig"
else
  printf '%s\n' "${instances[0]}"
fi

```

### scripts/hypr-win-focus.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

usage() {
  cat <<'EOF' >&2
usage: hypr-win-focus [--class REGEX] [--title REGEX] [--workspace NAME] [--icase] [--exec CMD]
EOF
}

class=""
title=""
workspace=""
icase=0
exec_cmd=""

while [[ "$#" -gt 0 ]]; do
  case "$1" in
    --class) class="${2:-}"; shift 2 ;;
    --title) title="${2:-}"; shift 2 ;;
    --workspace) workspace="${2:-}"; shift 2 ;;
    --icase) icase=1; shift ;;
    --exec) exec_cmd="${2:-}"; shift 2 ;;
    -h|--help) usage; exit 0 ;;
    *) echo "unknown arg: $1" >&2; usage; exit 1 ;;
  esac
done

if [[ -z "$class" && -z "$title" ]]; then
  usage
  exit 1
fi

python - "$class" "$title" "$workspace" "$icase" "$exec_cmd" <<'PY'
import json
import os
import re
import subprocess
import sys

cls = sys.argv[1]
title = sys.argv[2]
workspace = sys.argv[3]
icase = sys.argv[4] == "1"
exec_cmd = sys.argv[5]

flags = re.IGNORECASE if icase else 0

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
addr = None
for c in clients:
    if workspace and c.get("workspace", {}).get("name") != workspace:
        continue
    if cls and not re.search(cls, c.get("class", "") or "", flags):
        continue
    if title and not re.search(title, c.get("title", "") or "", flags):
        continue
    addr = c.get("address")
    break

if addr:
    subprocess.run(["hyprctl", "dispatch", "focuswindow", f"address:{addr}"])
    raise SystemExit(0)

if exec_cmd:
    subprocess.run(["hyprctl", "dispatch", "exec", exec_cmd])
    raise SystemExit(0)

raise SystemExit(1)
PY

```

### scripts/hypr-win-move.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

workspace="${1:-}"
follow=0

if [[ -z "$workspace" ]]; then
  echo "usage: hypr-win-move <workspace-name> [--follow]" >&2
  exit 1
fi

shift || true
if [[ "${1:-}" == "--follow" ]]; then
  follow=1
fi

hyprctl dispatch movetoworkspace "name:${workspace}"
if [[ "$follow" -eq 1 ]]; then
  hyprctl dispatch workspace "name:${workspace}"
fi

```

### scripts/hypr-win-float.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

size=""
center=0

while [[ "$#" -gt 0 ]]; do
  case "$1" in
    --size) size="${2:-}"; shift 2 ;;
    --center) center=1; shift ;;
    -h|--help)
      echo "usage: hypr-win-float [--size WxH] [--center]" >&2
      exit 0
      ;;
    *) echo "unknown arg: $1" >&2; exit 1 ;;
  esac
done

hyprctl dispatch togglefloating

if [[ -n "$size" ]]; then
  width="${size%x*}"
  height="${size#*x}"
  if [[ -n "$width" && -n "$height" ]]; then
    hyprctl dispatch resizeactive exact "$width" "$height"
  fi
fi

if [[ "$center" -eq 1 ]]; then
  hyprctl dispatch centerwindow
fi

```

### scripts/hypr-win-resize.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

mode=""
dx=""
dy=""

usage() {
  cat <<'EOF' >&2
usage:
  hypr-win-resize --exact <width> <height>
  hypr-win-resize --delta <dx> <dy>
EOF
}

if [[ "$#" -lt 3 ]]; then
  usage
  exit 1
fi

case "$1" in
  --exact) mode="exact"; shift ;;
  --delta) mode="delta"; shift ;;
  *) usage; exit 1 ;;
esac

dx="${1:-}"
dy="${2:-}"

if [[ -z "$dx" || -z "$dy" ]]; then
  usage
  exit 1
fi

if [[ "$mode" == "exact" ]]; then
  hyprctl dispatch resizeactive exact "$dx" "$dy"
else
  hyprctl dispatch resizeactive "$dx" "$dy"
fi

```

### scripts/hypr-win-pick.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

if ! command -v wofi >/dev/null 2>&1; then
  echo "wofi not installed" >&2
  exit 1
fi

selection="$(
  python - <<'PY' | wofi --show dmenu --prompt "Window"
import json
import subprocess

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
for c in clients:
    addr = c.get("address", "")
    ws = c.get("workspace", {}).get("name", "")
    klass = c.get("class", "")
    title = c.get("title", "")
    print(f"{ws} | {klass} | {title} | {addr}")
PY
)"

if [[ -z "$selection" ]]; then
  exit 0
fi

addr="${selection##* | }"
if [[ -n "$addr" ]]; then
  hyprctl dispatch focuswindow "address:${addr}"
fi

```

### scripts/hypr-list-clients.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

python - <<'PY'
import json
import subprocess

clients = json.loads(subprocess.check_output(["hyprctl", "-j", "clients"]))
for c in clients:
    addr = c.get("address", "")
    ws = c.get("workspace", {}).get("name", "")
    klass = c.get("class", "")
    title = c.get("title", "")
    print(f"{addr}\t{ws}\t{klass}\t{title}")
PY

```

### scripts/hypr-win-center.sh

```bash
#!/usr/bin/env bash
set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -z "${HYPRLAND_INSTANCE_SIGNATURE:-}" && -x "$script_dir/hypr-instance.sh" ]]; then
  inst="$("$script_dir/hypr-instance.sh" 2>/dev/null || true)"
  if [[ -n "$inst" ]]; then
    export HYPRLAND_INSTANCE_SIGNATURE="$inst"
  fi
fi

hyprctl dispatch centerwindow

```