I’m working on hyprland, one thing I am missing from my awesomewm setup is rofi list all running windows. Sometimes I put a browser instance in a different workspace and I cant find it, especially if I’ve full screened something over top of it.
first pass ¶ #
look for brave and go to it or make one
#!/usr/bin/env bash
addr=$(hyprctl clients -j | jq -r \
'.[] | select(.class == "brave-browser") | .address' | head -n1)
if [ -n "$addr" ]; then
# Focus the existing browser window
hyprctl dispatch focuswindow address:$addr
else
# Launch a new browser window
brave --password-store=basic &
fi
second pass ¶ #
If there are more than one cycle between them.
# Get current window address
current_addr=$(hyprctl activewindow -j | jq -r '.address')
# Get all Brave window addresses
brave_windows=($(hyprctl clients -j | jq -r '.[] | select(.class == "brave-browser") | .address'))
num_windows=${#brave_windows[@]}
if ((num_windows == 0)); then
# No Brave windows, launch it
brave --password-store=basic &
exit
fi
# Find the index of the current window in brave_windows
current_index=-1
for i in "${!brave_windows[@]}"; do
if [[ "${brave_windows[$i]}" == "$current_addr" ]]; then
current_index=$i
break
fi
done
# If we're already in a Brave window, switch to the next one (wrap around)
if ((current_index != -1)); then
next_index=$(((current_index + 1) % num_windows))
hyprctl dispatch focuswindow address:${brave_windows[$next_index]}
else
# Not currently in a Brave window — focus the first one
hyprctl dispatch focuswindow address:${brave_windows[0]}
fi
third pass ¶ #
Generalize it so that I can make keybindings for any app that I can figure out the classname of and provide a start command.
#!/usr/bin/env bash
set -euo pipefail
# Args
class="${1:-}"
shift
start_command="$*"
if [[ -z "$class" || -z "$start_command" ]]; then
echo "Usage: $0 <class> <start-command...>"
exit 1
fi
# Current active window
current_addr=$(hyprctl activewindow -j | jq -r '.address')
# All windows with matching class
matching_windows=($(hyprctl clients -j | jq -r --arg class "$class" '.[] | select(.class == $class) | .address'))
num_windows=${#matching_windows[@]}
if ((num_windows == 0)); then
# None running — start it
eval "$start_command" &
exit
fi
# See if currently focused window is in matching list
current_index=-1
for i in "${!matching_windows[@]}"; do
if [[ "${matching_windows[$i]}" == "$current_addr" ]]; then
current_index=$i
break
fi
done
# Cycle to next window if already in one
if ((current_index != -1)); then
next_index=$(((current_index + 1) % num_windows))
hyprctl dispatch focuswindow address:${matching_windows[$next_index]}
else
# Not in one — focus first
hyprctl dispatch focuswindow address:${matching_windows[0]}
fi
finding the classname ¶ #
❯ hyprctl clients -j | jq | grep kitty
"class": "kitty",
"initialClass": "kitty",
"initialTitle": "kitty",