diff options
| author | allusive-dev <[email protected]> | 2023-09-19 17:47:33 +1000 |
|---|---|---|
| committer | allusive-dev <[email protected]> | 2023-09-19 17:47:33 +1000 |
| commit | a93aba600b1c5d019b680b9f4ff3fa85d5d43a60 (patch) | |
| tree | 77f8152222655657472a70e0bfa413a0495dd555 /bin | |
| parent | reset (diff) | |
| download | compfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.tar.xz compfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.zip | |
Fixed broken files/code and other errors
Diffstat (limited to 'bin')
| -rw-r--r-- | bin/picom-trans | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/bin/picom-trans b/bin/picom-trans new file mode 100644 index 0000000..b686128 --- /dev/null +++ b/bin/picom-trans @@ -0,0 +1,407 @@ +#!/bin/sh +# SPDX-License-Identifier: MIT + +# +# picom-trans +# Copyright (c) 2021, Subhaditya Nath +# Based on previous works of Christopher Jeffrey +# + +# +# Conforming to POSIX-1.2007 +# https://pubs.opengroup.org/onlinepubs/9699919799 +# + +# 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 +# Toggle current window's opacity between 90 and unset +# $ picom-trans -c --toggle 90 +# Reset all windows +# $ picom-trans --reset + + +# Save $0 now to print correct value while printing from functions. +# Printing errormsgs from functions using "$0" prints the function name +# instead of the executable name. +EXE_NAME="$0" + + +# Instead of printing the full path to this file (e.g. /usr/bin/picom-trans) +# only print the base name (i.e. picom-trans) +EXE_NAME="$(basename "$EXE_NAME")" + + +print_usage() +{ #{{ + echo "Usage: $EXE_NAME [options] [+|-]opacity" + echo "" + echo "Options:" + echo " -h, --help Print this help message." + echo " -o, --opacity OPACITY Specify the new opacity value in range 0-100 for the window. If" + echo " prefixed with + or -, increment or decrement from the current" + echo " opacity of the target window." + echo "" + echo "Actions:" + echo " -g, --get Print current opacity of the target window." + echo " -d, --delete Delete opacity of the target window." + echo " -t, --toggle Toggle the target window's opacity, i.e. set if not already set" + echo " and delete else." + 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." +} #}} + + +parse_args() +{ #{{ + i=1 # because we start from "$1", not from "$0" + while [ $i -le $# ] + do + #### [START] Convert GNU longopts to POSIX equivalents #### + if [ "$1" = "--${1##--}" ] # check if $1 is a longopt + then + # Catch invalid options + case "$1" in + (--opacity=|--name=|--window=) + echo "$EXE_NAME: option ${1%=} needs a value" >&2 + exit 1;; + (--opacity|--name|--window) + test $i -eq $# \ + && echo "$EXE_NAME: option $1 needs a value" >&2 \ + && exit 1;; + esac + + # Separate "--ARG=VAL" into "--ARG" "VAL" + case "$1" in + (--opacity=*|--name=*|--window=*) + ARG="$(echo "$1" | sed -E 's/(--[^=]+)=.*$/\1/')" + VAL="${1##${ARG}=}" + shift && set -- "$ARG" "$VAL" "$@" + esac + + # Turn into short form + case "$1" in + (--help|--opacity|--get|--delete|--toggle|--reset|--select|--current|--name|--window) + ARG=${1#-} # remove one '-' from prefix + ARG="$(echo "$ARG" | cut -c -2)" # get first two characters + shift && set -- "$ARG" "$@" + esac + + # If the argument still starts with --, it is an invalid argument + case "$1" in + (--*) + echo "$EXE_NAME: illegal option $1" >&2 + exit 1 + esac + fi + #### [END] Convert GNU longopts to POSIX equivalents #### + + + #### [START] Prepend '-o' to standalone opacity values #### + # Iterate over every argument and check if it is an opacity without the -o + # option in the previous argument. If so, then prepend the -o option. + # e.g. Turn this - + # picom-trans -c +10 -s + # into this - + # picom-trans -c -o +10 -s + # + # NOTE: Don't touch arguments that are preceded by -o, -w, or -n (i.e. the + # options that take a value.) + # e.g. This - + # picom-trans -w 75 -o 90 + # should NOT be turned into this - + # picom-trans -w -o 75 -o 90 + # We ensure this by checking the "$#"th (i.e. the last) argument. If + # argument is an option that needs a value, we don't do anything to $1. + # + # NOTE: we are using printf because most echo implementations aren't + # POSIX-compliant. For example, according to POSIX.1-2017, echo doesn't + # support any options, so, + # $ echo "-n" + # should output - + # -n + # But it doesn't. It instead interprets the "-n" as the option -n, which, + # in most implementations, means that the trailing newline should not be + # printed. + if echo "$1" | grep -qE '^[+-]?[[:digit:]]+%?$' && \ + ! eval "printf '%s' \"\${$#}\"" | grep -q '^-[hdtrgsc]*[own]$' + # NOTE: eval "printf '%s' \"\${$#}\"" means 'print the last argument' + # NOTE: The letters inside the first square brackets (ie. hdtrgsc) are + # the same as those in the getopts argument, minus those that are + # followed by a ':' + # NOTE: The letters inside the second square brackets (ie. own) are + # the same as those in the getopts argument, minus those that are + # NOT followed by a ':' + then + set -- "$@" "-o" + i=$(( i + 1 )) + fi + #### [END] Prepend '-o' to standalone opacity values #### + + + # Prepare for next iteration + ARG="$1" + shift && set -- "$@" "$ARG" + i=$(( i + 1 )) + done + + + # NOTE: DO NOT ATTEMPT TO USE "$OPTIND" INSIDE THE getopts LOOP + # - https://github.com/yshui/picom/pull/634#discussion_r654571535 + # - https://www.mail-archive.com/austin-group-l%40opengroup.org/msg04112.html + OPTIND=1 + while getopts 'ho:dtrgsn:w:c' OPTION + do + case "$OPTION" in + (h) print_usage; exit 0;; + (o) target_opacity="$OPTARG";; + (d) action=delete;; + (t) action=toggle;; + (r) action=reset;; + (g) action=get;; + (s) winidtype=; winid=;; + (n) winidtype=-name; winid="$OPTARG";; + (w) winidtype=-id; winid="$OPTARG";; + (c) winidtype=-id; winid="$(get_focused_window_id)";; + (\?) exit 1 + esac + done +} #}} + + +get_target_window_id() +{ #{{ + + # Get the output of xwininfo + if test -z "$winidtype" + then xwininfo_output="$(xwininfo -children -frame)" + elif test "$winidtype" = "-name" + then xwininfo_output="$(xwininfo -children -name "$winid")" + elif test "$winidtype" = "-id" + then + # First, check if supplied window id is valid + if ! echo "$winid" | grep -Eiq '^[[:space:]]*(0x[[:xdigit:]]+|[[:digit:]]+)[[:space:]]*$' + then + echo "Bad window ID" >&2 + exit 1 + fi + xwininfo_output="$(xwininfo -children -id "$winid")" + fi + + # Extract window id from xwininfo output + winid="$(echo "$xwininfo_output" | sed -n 's/^xwininfo:.*: \(0x[[:xdigit:]]*\).*$/\1/p')" + if test -z "$winid" + then + echo "Failed to find window" >&2 + exit 1 + fi + + # Make sure it's not root window + if echo "$xwininfo_output" | grep -Fq "Parent window id: 0x0" + then + echo "Cannot set opacity on root window" >&2 + exit 1 + fi + + # If it's not the topmost window, get the topmost window + if ! echo "$xwininfo_output" | grep -q 'Parent window id: 0x[[:xdigit:]]* (the root window)' + then + window_tree="$(xwininfo -root -tree)" + if test -z "$window_tree" + then + echo "Failed to get root window tree" >&2 + exit 1 + fi + + # Find the highest ancestor of the target window + winid="$(echo "$window_tree" \ + | sed -n "/^\s*$winid/q;s/^ \(0x[[:xdigit:]]*\).*/\1/p" \ + | tail -n 1)" + if test -z "$winid" + then + echo "Failed to find window in window tree" >&2 + exit 1 + fi + fi + if test -z "$winid" + then + echo "Failed to find the highest parent window below root of the selected window" >&2 + exit 1 + fi + + echo "$winid" +} #}} + +get_focused_window_id() +{ #{{ + id="$(xprop -root -notype -f _NET_ACTIVE_WINDOW 32x '$0' _NET_ACTIVE_WINDOW)" + echo "${id#_NET_ACTIVE_WINDOW}" +} #}} + +get_current_opacity() +{ #{{ + # Gets current opacity in the range 0-100 + # Doesn't output anything if opacity isn't set + cur="$(xprop -id "$winid" -notype -f _NET_WM_WINDOW_OPACITY 32c '$0' _NET_WM_WINDOW_OPACITY)" + cur="${cur#_NET_WM_WINDOW_OPACITY}" + cur="${cur%:*}" + test -n "$cur" && + cur=$(( cur * 100 / 0xffffffff )) + echo "$cur" +} #}} + + +get_opacity() +{ #{{ + cur="$(get_current_opacity)" + test -z "$cur" && cur=100 # Unset opacity means fully opaque + echo "$cur" + exit 0 +} #}} + +delete_opacity() +{ #{{ + xprop -id "$winid" -remove _NET_WM_WINDOW_OPACITY + exit 0 +} #}} + +reset_opacity() # Reset opacity of all windows +{ #{{ + for winid in $(xwininfo -root -tree | sed -n 's/^ \(0x[[:xdigit:]]*\).*/\1/p') + do xprop -id "$winid" -remove _NET_WM_WINDOW_OPACITY 2>/dev/null + done + exit 0 +} #}} + +set_opacity() +{ #{{ + if ! echo "$target_opacity" | grep -qE '^[+-]?[[:digit:]]+%?$' + then + if test -z "$target_opacity" + then echo "No opacity specified" >&2 + else echo "Invalid opacity specified: $target_opacity" >&2 + fi + exit 1 + fi + + # strip trailing '%' sign, if any + target_opacity="${target_opacity%%%}" + + if echo "$target_opacity" | grep -q '^[+-]' + then + current_opacity="$(get_current_opacity)" + test -z "$current_opacity" && current_opacity=100 + target_opacity=$(( current_opacity + target_opacity )) + fi + + test $target_opacity -lt 0 && target_opacity=0 + test $target_opacity -gt 100 && target_opacity=100 + + target_opacity=$(( target_opacity * 0xffffffff / 100 )) + xprop -id "$winid" -f _NET_WM_WINDOW_OPACITY 32c \ + -set _NET_WM_WINDOW_OPACITY "$target_opacity" + + exit $? +} #}} + +toggle_opacity() +{ #{{ + # If opacity is currently set, unset it. + # If opacity is currently unset, set opacity to the supplied value. If no + # value is supplied, we default to 100%. + if test -z "$(get_current_opacity)" + then + test -n "$target_opacity" || target_opacity=100 + set_opacity + else + delete_opacity + fi +} #}} + + +# Warn about rename of compton to picom +case "$0" in + *compton-trans*) echo "Warning: compton has been renamed, please use picom-trans instead" >&2;; +esac + + +# Check if both xwininfo and xprop are available +if ! command -v xprop >/dev/null || ! command -v xwininfo >/dev/null +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 + + +# No arguments given. Show help. +if test $# -eq 0 +then + print_usage >&2 + exit 1 +fi + + +# Variables +# action is set to 'set' by default +action=set +winid= +winidtype= +target_opacity= + +# If there's only one argument, and it's a valid opacity +# then take it as target_opacity. Else, parse all arguments. +if test $# -eq 1 && echo "$1" | grep -qE '^[+-]?[[:digit:]]+%?$' +then + target_opacity=$1 + shift +else + parse_args "$@" +fi + + +# reset_opacity doesn't need $winid +case $action in + (reset) reset_opacity;; +esac + +# Any other action needs $winid +# +# NOTE: Do NOT change the order of winid= and winidtype= below +# the output of get_target_window_id depends on $winidtype +# +# NOTE: If get_target_window_id returns with a non-zero $? +# that must mean that some error occured. So, exit with that same $? +# +winid=$(get_target_window_id) || exit $? +winidtype=-id +case $action in + (set) set_opacity;; + (get) get_opacity;; + (delete) delete_opacity;; + (toggle) toggle_opacity;; +esac + + +# We should never reach this part of the file +echo "This sentence shouldn't have been printed. Please file a bug report." >&2 +exit 128 + + +# vim:ft=sh:ts=4:sts=4:sw=2:et:fdm=marker:fmr=#{{,#}}:nowrap |