#!/bin/sh # # picom-trans # transset in a bash script # Copyright (c) 2011-2012, Christopher Jeffrey # # Usage: # $ picom-trans [options] [+|-]opacity # By window id # $ picom-trans -w "$WINDOWID" 75 # By name # $ picom-trans -n "urxvt" 75 # By current window # $ picom-trans -c 75 # By selection # $ picom-trans 75 # $ picom-trans -s 75 # Increment current window 5% # $ picom-trans -c +5 # Delete current window's opacity # $ picom-trans -c --delete # Reset all windows # $ picom-trans --reset print_usage() { echo "Usage: $0 [options] [+|-]opacity" echo "" echo "Options:" echo " -h, --help Print this help message." echo " -o, --opacity OPACITY Specify the new opacity value in range 1-100 for the window. If" echo " prefixed with + or -, increment or decrement from the target" echo " window’s current opacity." echo "" echo "Actions:" echo " -g, --get Print the target window's opacity." echo " -d, --delete Delete opacity of the target window." echo " -r, --reset Reset opacity for all windows." echo "" echo "Window Selection:" echo " -s, --select Select target window with mouse cursor. (DEFAULT)" echo " -c, --current Select the currently active window as target." echo " -n, --name WINDOW_NAME Specify and try to match a window name." echo " -w, --window WINDOW_ID Specify the window id of the target window." } case "$0" in *compton-trans*) echo "Warning: compton has been renamed, please use picom-trans instead" >& 2;; esac # "command" is a shell built-in, faster than "which" if test -z "$(command -v xprop)" -o -z "$(command -v xwininfo)"; then echo 'The command xwininfo or xprop is not available. They might reside in a package named xwininfo, xprop, x11-utils, xorg-xprop, or xorg-xwininfo.' >& 2 exit 1 fi if test $# -eq 0; then print_usage >& 2 exit 1 fi # Variables active= wprefix= window= opacity= cur= action= treeout= wid= topmost= lineno= option= v= # Workaround: replace '-5' with '~5' so as not to confuse getopts. for v in "$@"; do shift && set -- "$@" "$(echo "$v" | sed 's/^-\([0-9]\+%\?\)$/~\1/')" done # This takes into account the fact that getopts stops on # any argument it doesn't recognize or errors on. This # allows for things like `picom-trans -5` as well # as `picom-trans -c +5 -s` (contrived example). while test $# -gt 0; do # Reset option index OPTIND=1 # Read options while getopts 'hscrdgn:w:o:-:' option "$@"; do if test "$option" = '-'; then case "$OPTARG" in help | select | current | reset | delete | get) v='' ;; name | window | opacity) eval v=\$$OPTIND OPTIND=$((OPTIND + 1)) ;; name=* | window=* | opacity=*) v=$(echo "$OPTARG" | sed 's/^[^=]\+=//') ;; *) echo "$0: illegal option $OPTARG" >& 2 exit 1 ;; esac option=$(echo "$OPTARG" | cut -c 1) OPTARG=$v fi case "$option" in h) print_usage; exit 0 ;; s) wprefix=''; window='' ;; c) active=$(xprop -root -notype _NET_ACTIVE_WINDOW \ | grep -Eo '0x[[:xdigit:]]+' | head -n 1) wprefix='-id'; window=$active ;; r) action='reset' ;; d) action='delete' ;; g) action='get' ;; n) wprefix='-name'; window=$OPTARG ;; w) wprefix='-id'; window=$OPTARG ;; o) opacity=$OPTARG ;; \?) exit 1 ;; esac done # Read positional arguments shift $((OPTIND - 1)) test -n "$1" && opacity=$1 && shift done # clean up opacity. xargs == a poor man's trim. opacity=$(echo "$opacity" | xargs | sed 's/%//g' | sed 's/^~\([0-9]\+\)$/-\1/') # Validate opacity value if test -z "$action" && ! echo "$opacity" | grep -q '^[+-]\?[0-9]\+$'; then echo "Invalid opacity specified: $opacity." exit 1 fi # Reset opacity for all windows if test x"$action" = x'reset'; then xwininfo -root -tree \ | sed -n 's/^ \(0x[[:xdigit:]]*\).*/\1/p' \ | while IFS=$(printf '\n') read wid; do xprop -id "$wid" -remove _NET_WM_WINDOW_OPACITY done exit 0 fi # Get ID of the target window if test -z "$wprefix"; then treeout=$(xwininfo -children -frame) else test "$wprefix" = '-id' \ && ! echo "$window" | grep -Eiq '^[[:space:]]*(0x[[:xdigit:]]+|[[:digit:]]+)[[:space:]]*$' \ && echo 'Bad window ID.' && exit 1 treeout=$(xwininfo -children $wprefix "$window") fi wid=$(echo "$treeout" | sed -n 's/^xwininfo:.*: \(0x[[:xdigit:]]*\).*$/\1/p') if test -z "$wid"; then echo 'Failed to find window.' exit 1 fi # Make sure it's not root window if echo "$treeout" | fgrep -q 'Parent window id: 0x0'; then echo 'Cannot set opacity on root window.' exit 1 fi # If it's already the topmost window if echo "$treeout" | grep -q 'Parent window id: 0x[[:xdigit:]]* (the root window)'; then topmost=$wid else # Get the whole window tree treeout=$(xwininfo -root -tree) if test -z "$treeout"; then echo 'Failed to get root window tree.' exit 1 fi # Find the line number of the target window in the window tree lineno=$(echo -n "$treeout" | grep -nw "^\s*$wid" | head -n1 | cut -d ':' -f 1) if test -z "$lineno"; then echo 'Failed to find window in window tree.' exit 1 fi # Find the highest ancestor of the target window below topmost=$(echo -n "$treeout" \ | head -n $lineno \ | sed -n 's/^ \(0x[[:xdigit:]]*\).*/\1/p' \ | tail -n 1) fi if test -z "$topmost"; then echo 'Failed to find the highest parent window below root of the' \ 'selected window.' exit 1 fi # Remove the opacity property. if test x"$action" = x'delete'; then xprop -id "$topmost" -remove _NET_WM_WINDOW_OPACITY exit 0 fi # Get current opacity. cur=$(xprop -id "$topmost" -notype _NET_WM_WINDOW_OPACITY \ | sed 's/^.*\b\([0-9]\+\).*$\|^.*$/\1/') test -z "$cur" && cur=0xffffffff cur=$((cur * 100 / 0xffffffff)) # Output current opacity. if test x"$action" = x'get'; then echo "$cur" exit 0 fi # Calculate the desired opacity if echo "$opacity" | grep -q '^[+-]'; then opacity=$((cur + opacity)) fi test $opacity -lt 0 && opacity=0 test $opacity -gt 100 && opacity=100 # Set opacity opacity=$((opacity * 0xffffffff / 100)) xprop -id "$topmost" -f _NET_WM_WINDOW_OPACITY 32c \ -set _NET_WM_WINDOW_OPACITY "$opacity"