Skip to content

Instantly share code, notes, and snippets.

@Misko-2083
Created May 2, 2018 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Misko-2083/3a360a1f2d913154e6384a88b1ca6d49 to your computer and use it in GitHub Desktop.
Save Misko-2083/3a360a1f2d913154e6384a88b1ca6d49 to your computer and use it in GitHub Desktop.
window switcher, bash, yad UI
#!/bin/bash
#######################################################
# Description: #
# bash script to list and focus windows #
# via yad list UI Misko_2083 #
#######################################################
ERR(){ echo "ERROR: $1" 1>&2; }
declare -i DEPCOUNT=0
for DEP in /usr/bin/{xdotool,perl,wmctrl,yad,convert,xprop,awk,xargs,iconv} /bin/{rm,echo,sed}; {
[ -x "$DEP" ] || {
ERR "$LINENO Dependency '$DEP' not met."
DEPCOUNT+=1
}
}
[ $DEPCOUNT -eq 0 ] || exit 1
VERSION=`yad --version | awk '{ print $1 }'`
verlte() {
[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
}
verlt() {
[ "$1" = "$2" ] && return 1 || verlte $1 $2
}
if verlt $VERSION 0.38.2; then
yad --text=" The version of yad installed is too old for to run this program, \n Please upgrade yad to a version higher than 0.38.2 " \
--button="gtk-close"
exit
fi
# Ensures only one instance of this scipt can start
# Also, if there is another yad window closes it
if [[ $(pgrep -c $(basename $0)) -ne 1 ]]; then
pids="$(xdotool search --class "wlist")"
wpid="$(xdotool getwindowfocus)"
for pid in $pids; do
# Compares window class pid with the pid of a window in focus
if [[ "$pid" == "$wpid" ]]; then
xdotool windowunmap $pid
exit 1
fi
done
fi
# Check if there are windows present
wmctrl -l | while read -a A; do
if [[ "${A[1]}" -ge "0" ]];then
exit 1
fi
done
if [[ "$?" -eq 0 ]]; then
yad --text="Window list:\nNo windows to show." \
--no-buttons \
--undecorated \
--close-on-unfocus \
--on-top \
--skip-taskbar \
--mouse \
--sticky \
--class="wlist"
exit 0
fi
#######################################################
# Note: #
# to show the icon for the "zathura" application #
# create a config file ~/.config/zathura/zathurarc #
# with contents: set window-icon /path/to/zathura.png #
# there is a manual page for zathurarc: man zathurarc #
#######################################################
# Activation method can be select or dclick
# select - focus window on selection
# dclick - focus window on double-click
ACTION=select
gtkIcons=Default
# Get Icon Theme name Mate desktop
gtkIcons=$(gsettings get org.mate.interface icon-theme)
gtkIcons=${gtkIcons//"'"}
# Get icon theme bunsen hidrogen
# gtkIcons="$(awk -F'"' '/^gtk-icon-theme-name/{print $2}' ~/.gtkrc-2.0)"
# Get Icon Theme Name Xfce Desktop
# gtkIcons=$(xfconf-query -c xsettings -p /Net/IconThemeName)
#######################################################
# Temp Dir to store the icon cache: #
# This directory is used to store the icon cache #
# Change it for your needs #
#######################################################
# Temp Dir to store the icon cache
TMPDIR="~/Desktop/wlist-icons/$gtkIcons"
if [[ ! -d "$TMPDIR" ]]
then
mkdir -p "$TMPDIR"
fi
# Get active window id
ACTIVE_WIN_ID=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | awk '{print $2}')
# With process substitution output from "wmctrl -l" is redirected here
# while loop reads "win_id" and "display" variables
while read -r win_id display app text
do
# Skip sticky windows with display id -1
[[ "$display" -eq "-1" ]] && continue
# Get WM_CLASS X window property
wm_class="$(xprop -id $win_id WM_CLASS | awk -F'"' '{print tolower($4)}')"
if [[ ! -f $TMPDIR/$wm_class.png ]]
then
# Converts icons to pam then uses imagemagick to convert to png and resize to 16x16
xprop -notype 32c -id $win_id _NET_WM_ICON \
| perl -0777 -pe '@_=/\d+/g;
printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2;
$_=pack "N*", @_;
s/(.)(...)/$2$1/gs' \
| convert pam:- -resize 16x16 $TMPDIR/$wm_class.png 2>/dev/null
if [[ $? -ne 0 ]] && [[ ! -f "$TMPDIR/$wm_class" ]]
then
NET_NAME=$(xprop -id $win_id _NET_WM_NAME | awk -F '"' '{print $2}')
echo "$NET_NAME" > "$TMPDIR/$wm_class"
fi
fi
# Extracts the application name from string
app="${app##*'.'}"
# makes active window row bold
if [[ "$win_id" -eq "$ACTIVE_WIN_ID" ]]
then
#display="<b>$display</b>"
app="<b>$app</b>"
text="<b>$text</b>"
fi
# if WM_CLASS is a "Wrapper"
if [[ "${wm_class}" == "Wrapper" ]]
then
# Get WM_CLASS X window property _NET_WM_NAME
wm_class=$(xprop -id $win_id _NET_WM_NAME | awk -F '"' '{print $2}')
# print to yad columns
if [[ "$wm_class" -ne "" ]]
then
echo "$wm_class"
else
echo "xfwm4"
fi
echo "$win_id" # We use this one for select-action (hidden column)
echo "$text" | sed "s/\&/\&amp;/g" | # escape ampersand, yad doesn't like it
iconv -c -t UTF-8 # convert characters to utf-8, yad again
echo "$display ${wm_class}" | sed "s/\&/\&amp;/g"
else
if [[ -f $TMPDIR/$wm_class.png ]]
then
echo "$TMPDIR/$wm_class.png"
elif [[ -s "$TMPDIR/$wm_class" ]]
then
cat "$TMPDIR/$wm_class"
else
echo "$wm_class"
fi
# print to yad columns
echo "$win_id" # We use this one for select-action (hidden column)
echo "$text" | sed "s/\&/\&amp;/g" | # escape ampersand, yad doesn't like it
iconv -c -t UTF-8 # convert characters to utf-8, yad again
echo "$display ${app}" | sed "s/\&/\&amp;/g"
fi
done < <(wmctrl -l -x \
| awk '{$4="";
if($3=="zathura.Zathura")
print $1, $2, substr($0, index($0,$5), 50);
else
print $1, $2, $3, substr($0, index($0,$5), 50);}') \
| yad --list \
--title="WList" \
--column="icon":IMG \
--column="win_id" \
--column="title" \
--column="display / app" \
--width="500" \
--height="450" \
--hide-column="2" \
--$ACTION-action="sh -c \"echo %s | cut -d ' ' -f 2 2>&1 | xargs xdotool windowactivate -- \"" \
--no-buttons \
--search-column=3 \
--window-icon="mate-desktop" \
--undecorated \
--close-on-unfocus \
--on-top \
--skip-taskbar \
--mouse \
--sticky \
--class="wlist"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment