#!/bin/sh #description: dmenu-i3-window-jumper is a window selector for i3-wm #usage: dmenu-i3-window-jumper is best suited to be launched from a shortcut (tab) #example: dmenu-i3-window-jumper #a gui menu appears asking which windows jump to progname="$(expr "${0}" : '.*/\([^/]*\)')" #variables are impractical to save complex cmds because of shell expantion #therefore functions are required: http://mywiki.wooledge.org/BashFAQ/050 DMENU() { dmenu -p 'Jump to' -l 20 -i -fn Bahamas-10 \ -nb \#000000 -nf \#ffffff -sb \#c0c0c0 -sf \#000000; } #looks better on xft powered dmenu: #https://bugs.launchpad.net/ubuntu/+source/suckless-tools/+bug/1093745 _usage() { printf "%s\\n" "Usage: ${progname} [app|title]" printf "%s\\n" "Dmenu window selector for i3-wm." printf "%s\\n" printf "%s\\n" " -h, --help show this message and exit" } _die() { [ -n "${1}" ] && _die_msg="${1}" || exit 1 printf "%b%b\\n" "${_die_msg}" ", press to exit" | DMENU exit 1 } _i3_get_app_tree() { i3-msg -t get_tree | \ egrep -o "(class\":\".[^\"]+\"|title\":\"[^\"]+)" | \ sed 's/"//g;s/class://g;s/title://g' | \ while read -r line; read -r line2; do \ printf "%s\\n" "═ ${line} :: ${line2}"; \ done | sed '/i3bar for/d' #alternative #i3-msg -t get_tree | python -mjson.tool | \ #sed -n -e 's/^ \{35\}[ ]\+\"name\": \"\(.*\)\", $/\1/p' | \ #sed '/^#[a-F0-9]\{6\}$/d' } if [ ! -t 0 ]; then #add input comming from pipe or file to $@ set -- "${@}" $(cat) fi for arg in "${@}"; do #parse options case "${arg}" in -h|--help) _usage && exit ;; esac done if [ -z "${1}" ]; then if ! command -v "dmenu" >/dev/null 2>&1; then printf "%s\\n" "${progname}: install 'dmenu' to run this program" >&2 exit 1 fi selected_entry="$(_i3_get_app_tree | DMENU)" else selected_entry="$(_i3_get_app_tree | grep -i "${@}" 2>/dev/null | head -1 )" fi if [ -z "${selected_entry}" ]; then _die else #escape some characters to prevent i3 to interpret them as a pattern # "(" and ")" replace them with "\(" and "\)" #title="$(printf "%s\\n" "${windows}" | sed 's/\([()]\)/\\\1/g')" title="$(printf "%s\\n" "${selected_entry}" | \ egrep -o "::.*" | sed 's/:: //g;s/\([()]\)/\\\1/g')" #focus window output_msg="$(i3-msg "[title=\"${title}\"] focus" 2>&1)" if printf "%s\\n" "${output_msg}" | tail -1 | \ grep "success" | grep "false" >/dev/null 2>&1; then app="${title}"; i3-msg "[class=\"${app}\"] focus" fi fi