Skip to content

Instantly share code, notes, and snippets.

@piersolenski
Created October 23, 2025 20:41
Show Gist options
  • Save piersolenski/6b0ff1e6b7cb6200f4074877c41d9162 to your computer and use it in GitHub Desktop.
Save piersolenski/6b0ff1e6b7cb6200f4074877c41d9162 to your computer and use it in GitHub Desktop.
Spawn or focus Niri windows
#! /usr/bin/env bash
# Spawn-or-focus script for Niri window manager
# Launches an application if not running, focuses it if already open,
# or returns to previous window if the application is already focused.
#
# Usage: spawn-or-focus.sh <app-name>
#
# Example keybinding in niri config:
# Mod+T { spawn "sh" "-c" "~/.config/niri/spawn-or-focus.sh terminal"; }
# Check if an argument is provided
if [ -z "$1" ]; then
echo "Error: No argument provided."
exit 1
fi
# Applications
terminal="ghostty"
browser="brave-browser"
# Commands to run the programs
# The case statements need the app-id of the program.
case "$1" in
"calendar")
cmd="$browser --profile-directory=Default --app-id=kjbdgfilnfhdoflbpgamdcdgpehopbep"
;;
"email")
cmd="$terminal --class=com.piers.email -e aerc"
;;
"browser")
cmd="$browser"
;;
"ferdium")
cmd="flatpak run org.ferdium.Ferdium"
;;
"spotify")
cmd="$terminal --class=com.piers.spotify -e spotify_player"
;;
"terminal")
cmd="$terminal --class=com.piers.terminal -e zsh -ic 'tmux attach || tmux'"
;;
"top")
cmd="$terminal --class=com.piers.top -e zsh -ic btop"
;;
"yazi")
cmd="$terminal --class=com.piers.yazi -e yazi"
;;
*)
echo "Unhandled case provided. Exiting"
exit 1
;;
esac
# Get window info from niri msg windows output
# Search by app_id only to avoid false matches in window titles
WIN_INFO=$(niri msg -j windows | jq --arg search "$1" '.[] | select (.app_id | test($search)) | { id, is_focused }')
ID=$(echo "$WIN_INFO" | jq -r '.id // empty')
IS_FOCUSED=$(echo "$WIN_INFO" | jq -r '.is_focused // empty')
# Spawn window if it's not open, or focus the window if it's already open
if [ -z "$ID" ]; then
niri msg action spawn -- "sh" "-c" "$cmd"
elif [ "$IS_FOCUSED" = "true" ]; then
niri msg action focus-window-previous
else
niri msg action focus-window --id "$ID"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment