2022-11-22 17:53:53 -05:00
#!/bin/bash
# Configures the i3 window manager to make it screen reader accessible
# Written by Storm Dragon
# Released under the terms of the WTFPL http://www.wtfpl.net
i3Path = " ${ XDG_CONFIG_HOME :- $HOME /.config } /i3 "
# Dialog accessibility
export DIALOGOPTS = '--no-lines --visit-items'
# Check to make sure minimum requirements are installed.
2022-11-22 21:11:29 -05:00
for i in dialog sgtk-menu yad ; do
2022-11-22 17:53:53 -05:00
if ! command -v " $i " & > /dev/null ; then
missing += ( " $i " )
fi
done
if [ [ -n " ${ missing } " ] ] ; then
echo "Please install the following packages and run this script again:"
echo " ${ missing [*] } "
exit 1
fi
menulist( ) {
# Args: List of items for menu.
# returns: selected tag
local menuText = " $1 "
shift
local menuList
for i in " ${ @ } " ; do
menuList += ( " $i " " $i " )
done
dialog --title "Strychnine" \
--backtitle "Use the arrow keys to find the option you want, and enter to select it." \
--clear \
--no-tags \
--menu " $menuText " 0 0 0 ${ menuList [@] } --stdout
return $?
}
# rangebox
# $1 text to show
# $2 minimum value
# $3 maximum value
# $4 Default value
rangebox( ) {
dialog --title "Strychnine" \
--backtitle "Use the arrow keys to select a number, then press enter." \
--rangebox " $1 " -1 -1 $2 $3 $4 --stdout
}
yesno( ) {
# Returns: Yes 0 or No 1
# Args: Question to user.
dialog --clear --title "Strychnine" --yesno " $* " -1 -1 --stdout && return 0
}
2022-11-22 21:11:29 -05:00
help( ) {
echo " ${ 0 ##*/ } "
echo "Released under the terms of the WTFPL License: http://www.wtfpl.net"
echo -e "This is a Stormux project: https://stormux.org\n"
echo -e "Usage:\n"
echo "With no arguments, create the i3 configuration."
for i in " ${ !command[@] } " ; do
echo " - ${ i / : / <parameter> } : ${ command [ ${ i } ] } "
done | sort
exit 0
}
2022-11-22 17:53:53 -05:00
write_xinitrc( )
{
if [ [ -f " $HOME /.xinitrc " ] ] ; then
continue = " $( yesno " This will overwrite your existing $HOME /.xinitrc file. Do you want to continue? " ) "
if [ " $continue " = "no" ] ; then
exit 0
fi
fi
cat << 'EOF' > ~/.xinitrc
#!/bin/sh
#
# ~/.xinitrc
#
# Executed by startx (run your window manager from here)
dbus-launch
[ [ -f ~/.Xresources ] ] && xrdb -merge -I$HOME ~/.Xresources
if [ -d /etc/X11/xinit/xinitrc.d ] ; then
for f in /etc/X11/xinit/xinitrc.d/*; do
[ -x " $f " ] && . " $f "
done
unset f
fi
[ -f /etc/xprofile ] && . /etc/xprofile
[ -f ~/.xprofile ] && . ~/.xprofile
export DBUS_SESSION_BUS_PID
export DBUS_SESSION_BUS_ADDRESS
exec i3
EOF
if [ [ -f " $HOME /.xprofile " ] ] ; then
continue = " $( yesno " Would you like to add accessibility variables to your $HOME /.xprofile? Without these, accessibility will be limited or may not work at all. Do you want to continue? " ) "
if [ " $continue " = "no" ] ; then
exit 0
fi
fi
cat << 'EOF' > ~/.xprofile
# Accessibility variables
export ACCESSIBILITY_ENABLED = 1
export GTK_MODULES = gail:atk-bridge
export GNOME_ACCESSIBILITY = 1
export QT_ACCESSIBILITY = 1
export QT_LINUX_ACCESSIBILITY_ALWAYS_ON = 1
EOF
}
add_setting( )
{
if [ -z " $rc " ] ; then
rc = " $@ "
else
rc = " ${ rc } " $'\n' " $@ "
fi
}
2022-11-22 21:11:29 -05:00
# Array of command line arguments
declare -A command = (
[ h] = "This help screen."
)
# Convert the keys of the associative array to a format usable by getopts
args = " ${ !command[*] } "
args = " ${ args //[[ : space : ]]/ } "
while getopts " ${ args } " i ; do
case " $i " in
h) help; ;
esac
done
2022-11-22 17:53:53 -05:00
# Create .xinitrc file if requested
if [ [ " $1 " = "-x" || " $1 " = "--xinitrc" ] ] ; then
write_xinitrc
exit 0
fi
# Make sure rc variable is empty
unset rc
# Set path for helper scripts.
path = " $( readlink -f $0 ) "
path = " ${ path %/* } "
if ! command -v notify-send & > /dev/null ; then
timeOut = " $( rangebox "Seconds for notifications:" 3 10 5) "
notify = " yad --info --timeout $timeOut --no-buttons --title 'notification' --text "
else
notify = "notify-send"
fi
add_setting " # Generated by strychnine ( ${ 0 ##*/ } ) https://git.2mb.codes/~stormdragon2976/strychnine " $'\n' " # $( date '+%A, %B %d, %Y at %I:%M%p' ) " $'\n' $'\n' "# Miscellaneous"
add_setting startup_message off
add_setting set winname title
add_setting "set bgcolor #000000"
add_setting "set fgcolor #FFFFFF"
add_setting 'set font -*-terminus-medium-r-normal-*-24-*-*-*-*-*-*-*'
add_setting set waitcursor 1
add_setting banish
# Unbind existing keys that lead to inaccessible things like xterm or keys that user wants to change, or don't make sense for blind users:
add_setting $'\n' "# Unbind section"
add_setting unbind C-A
add_setting unbind A
add_setting unbind C-a
add_setting unbind a
add_setting unbind c
add_setting unbind C-c
add_setting unbind C-f
add_setting unbind F
add_setting unbind r
add_setting unbind C-r
add_setting unbind S
add_setting unbind C-S
add_setting unbind s
add_setting unbind C-s
add_setting unbind C-t
add_setting unbind C-v
add_setting unbind v
add_setting unbind C-w
add_setting unbind C-Down
add_setting unbind Down
add_setting unbind C-exclam
add_setting unbind exclam
add_setting unbind C-Left
add_setting unbind Left
add_setting unbind question
add_setting unbind C-Right
add_setting unbind Right
add_setting unbind C-Up
add_setting unbind Up
add_setting unbind C-apostrophe
add_setting unbind apostrophe
add_setting unbind colon
escapeKey = " $( menulist "Ratpoison escape key:" C-t C-z -C-Escape M-Escape C-space Super_L Super_R) "
if [ " $escapeKey " != "C-t" ] ; then
add_setting unbind t
fi
# Key binding section
add_setting $'\n' "# Key binding section"
# Key binding section
if [ " $escapeKey " != "C-t" ] ; then
add_setting escape $escapeKey
fi
add_setting "# Alt+f1 applications menu"
add_setting definekey top M-F1 exec yad --icons --compact --no-buttons --title= \" Ratpoison Applications Menu\" --close-on-unfocus --read-dir= /usr/share/applications
add_setting "# Alt+f2 executes the run dialog"
add_setting definekey top M-F2 run_dialog
add_setting "# Alt+f3 local applications menu"
add_setting definekey top M-F3 exec yad --icons --compact --no-buttons --title= \" Ratpoison Local Applications Menu\" --close-on-unfocus --read-dir= ${ HOME } /.local/share/applications
add_setting "# Control+Alt+d Desktop"
add_setting definekey top C-M-d exec yad --icons --compact --no-buttons --title= \" Ratpoison Desktop Menu\" --close-on-unfocus --read-dir= ${ HOME } /Desktop
add_setting "# Alt+tab switches through open windows"
add_setting definekey top M-Tab next
add_setting definekey top M-ISO_Left_Tab prev
add_setting definekey top M-F4 close_window
add_setting "# Media key bindings"
add_setting definekey top XF86AudioPrev music_player_previous_track
add_setting definekey top XF86AudioMute music_player_pause
add_setting definekey top XF86AudioPlay music_player_play
add_setting definekey top XF86AudioStop music_player_stop
add_setting definekey top XF86AudioNext music_player_next_track
add_setting definekey top XF86AudioLowerVolume music_player_decrease_volume
add_setting definekey top XF86AudioRaiseVolume music_player_increase_volume
add_alias alias close_window exec ratpoison -c 'delete'
if command -v ocrdesktop & > /dev/null ; then
add_setting definekey top Print exec $( command -v ocrdesktop) -d
fi
add_setting bind exclam run_dialog
add_alias alias ratpoison_keybindings exec 'f=$(mktemp);ratpoison -c "help root" > $f && yad --text-info --show-cursor --title "Ratpoison Keybindings" --button "Close:0" --filename "$f";rm "$f"'
add_setting bind question ratpoison_keybindings
# Figure out which terminal emulator to use:
unset programList
for i in gnome-terminal lxterminal mate-terminal terminator tilda xfce4-terminal; do
if hash ${ i /#-/ } & > /dev/null ; then
if [ -n " $programList " ] ; then
programList = " $programList $i "
else
programList = " $i "
fi
fi
done
if [ -z " $programList " ] ; then
die "No terminal emulator found, please install one of lxterminal mate-terminal terminator, or xfce4-terminal."
fi
if [ " $programList " != " ${ programList // / } " ] ; then
terminal = " $( menulist "Terminal emulator:" $programList ) "
else
terminal = " ${ programList /#-/ } "
fi
# Configure file browser
unset programList
for i in caja nemo nautilus pcmanfm pcmanfm-qt thunar ; do
if hash ${ i /#-/ } & > /dev/null ; then
if [ -n " $programList " ] ; then
programList = " $programList $i "
else
programList = " $i "
fi
fi
done
if [ " $programList " != " ${ programList // / } " ] ; then
fileBrowser = " $( menulist "File browser:" $programList ) "
else
fileBrowser = " ${ programList /#-/ } "
fi
if [ -n " $fileBrowser " ] ; then
fileBrowser = " $( command -v $fileBrowser ) "
fi
add_setting bind f exec $fileBrowser
# Configure web browser
unset programList
for i in brave chromium epiphany firefox google-chrome-stable midori seamonkey ; do
if hash ${ i /#-/ } & > /dev/null ; then
if [ -n " $programList " ] ; then
programList = " $programList $i "
else
programList = " $i "
fi
fi
done
if [ " $programList " != " ${ programList // / } " ] ; then
webBrowser = " $( menulist "Web browser:" $programList ) "
else
webBrowser = " ${ programList /#-/ } "
fi
if [ -n " $webBrowser " ] ; then
webBrowser = " $( command -v $webBrowser ) "
fi
add_setting bind w exec $webBrowser
add_setting bind W exec $webBrowser '$(ratpoison -c getsel) # Open selected URI in web browser'
# Configure text editor
unset programList
for i in geany gedit kate kwrite l3afpad leafpad libreoffice mousepad pluma ; do
if hash ${ i /#-/ } & > /dev/null ; then
if [ -n " $programList " ] ; then
programList = " $programList $i "
else
programList = " $i "
fi
fi
done
if [ " $programList " != " ${ programList // / } " ] ; then
textEditor = " $( menulist "Text editor:" $programList ) "
else
textEditor = " ${ programList /#-/ } "
fi
if [ -n " $textEditor " ] ; then
textEditor = " /usr/bin/ $textEditor "
fi
add_setting bind e exec $textEditor
if hash gasher & > /dev/null ; then
add_setting bind g exec EDITOR = " $textEditor " gasher -p '# Post to GNU Social with Gasher'
fi
if hash mumble & > /dev/null ; then
add_setting bind m exec /usr/bin/mumble
fi
if command -v pidgin & > /dev/null ; then
add_setting bind p exec $( command -v pidgin)
fi
if command -v talking-clock & > /dev/null ; then
add_setting bind M-t exec $( command -v talking-clock) '-c'
fi
add_setting bind c exec /usr/bin/$terminal
add_setting bind C-c exec /usr/bin/$terminal
add_setting "# Music player bindings:"
add_alias " alias music_player_previous_track exec playerctl previous && $notify \"\$(playerctl metadata -f ' " { { title} } " by " { { artist} } "')\""
add_alias " alias music_player_play exec playerctl play && $notify \"\$(playerctl metadata -f ' " { { title} } " by " { { artist} } "')\""
add_alias " alias music_player_pause exec playerctl play-pause && $notify \"\$(playerctl metadata -f ' " { { title} } " by " { { artist} } " {{status}}')\""
add_alias "alias music_player_stop exec playerctl stop"
add_alias " alias music_player_next_track exec playerctl next && $notify \"\$(playerctl metadata -f ' " { { title} } " by " { { artist} } "')\""
add_alias "alias music_player_decrease_volume exec playerctl volume 0.5-"
add_alias "alias music_player_increase_volume exec playerctl volume 0.5+"
add_alias " alias music_player_show_info exec $notify \"\$(playerctl metadata -f ' " { { title} } " by " { { artist} } " from " { { album} } " via {{playerName}}')\""
add_setting "bind M-Z music_player_previous_track"
add_setting "bind M-X music_player_play"
add_setting "bind M-C music_player_pause"
add_setting "bind M-V music_player_stop"
add_setting "bind M-B music_player_next_track"
add_setting "bind M-underscore music_player_decrease_volume"
add_setting "bind M-plus music_player_increase_volume"
add_setting "bind M-U music_player_show_info"
add_alias 'alias run_dialog exec historyPath="${XDG_CONFIG_HOME:-$HOME/.config}/strychnine";if ! [ -d "$historyPath" ]; then mkdir -p "$historyPath";fi;write_history(){ oldHistory="$(grep -v "$txt" "$historyPath/history" | head -n 49)";echo -e "$txt\n$oldHistory" | sed ' " 's/^ $//g' " ' > "$historyPath/history"; };if [ -f "$historyPath/history" ]; then txt=$(yad --entry --editable --title "Ratpoison" --text "Execute program or enter file" --button "Open:0" --separator "\n" --rest "$historyPath/history");else txt=$(yad --entry --title "Ratpoison" --text "Execute program or enter file" --button "Open:0");fi;if [ -z "$txt" ]; then exit 0;fi;if [[ "$txt" =~ ^ftp://|http://|https://|www.* ]]; then ' " $webBrowser " ' $txt;write_history;exit 0;fi;if [[ "$txt" =~ ^mailto://.* ]]; then xdg-email $txt;write_history;exit 0;fi;if [[ "$txt" =~ ^man://.* ]]; then eval "${txt/:\/\// }" | yad --text-info --show-cursor --button "Close:0" --title "Ratpoison" -;write_history;exit 0;fi;if command -v "$(echo "$txt" | cut -d " " -f1)" &> /dev/null ; then eval $txt& else xdg-open $txt&fi;write_history;exit 0'
add_alias 'alias run_in_terminal_dialog exec c="$(yad --entry --title "Ratpoison" --text "Enter command:")" &&' /usr/bin/$terminal -e '$c'
add_setting bind C-exclam run_in_terminal_dialog
add_alias alias set_window_name exec 't="$(yad --entry --title "Ratpoison" --text "Enter window name") && ratpoison -c "title $t"'
add_setting bind C-A set_window_name
add_setting bind A set_window_name
add_alias alias show_date exec " $notify " '"$(date +"%A, %B %d, %Y%n%I:%M%p")"'
add_setting bind C-a show_date
add_setting bind a show_date
add_setting bind C-t show_date
add_setting bind O exec /usr/bin/orca -r '# Restart Orca'
add_alias alias ratpoison_version exec " $notify " '"$(ratpoison -c "version")"'
add_setting bind C-v ratpoison_version
add_setting bind v ratpoison_version
add_alias alias window_menu exec 'ifs="$IFS";IFS=$' "'" \\ n"'" ';w="$(yad --list --title "Ratpoison" --text "Select Window" --column "Select" $(ratpoison -c "windows"))";IFS="$ifs";ratpoison -c "select ${w:0:1}"'
add_setting bind C-apostrophe window_menu
add_setting bind apostrophe window_menu
add_alias alias run_ratpoison_command exec 'c="$(yad --entry --title "Ratpoison" --text="Enter Ratpoison command:")" && ratpoison -c "$c"'
add_setting bind colon run_ratpoison_command
add_alias alias reload_ratpoison_configuration exec ratpoison -c " \"source $HOME /.ratpoisonrc\"&& $notify \"Ratpoison configuration reloaded\" "
add_setting bind C-colon reload_ratpoison_configuration
add_setting bind C-M-r restart
add_setting bind C-M-q quit
# Sound for new window.
windowSound = " $( yesno "Should new windows, and ratpoison keys make sounds?" ) "
#add_alias addhook switchwin speak_window_title
if [ [ " $windowSound " = = "yes" ] ] ; then
add_alias addhook newwindow announce_new_window
add_alias addhook key announce_top_level_key
add_alias alias announce_new_window exec bash -c $'\'excludedWindowNames="zenity";winName="$(ratpoison -c "info %t")";if ! [[ "$winName" =~ ^(${excludedWindowNames})$ ]]; then play -n synth .25 sin 440:880 sin 480:920 remix - norm -3 pitch -500;fi\''
add_alias alias announce_top_level_key exec 'play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20'
#add_alias alias 'speak_window_title exec bash -c' "'"'windowName="$(ratpoison -c "info %t")";socketFile="$(find /tmp -maxdepth 1 -name "orca-*.sock")"; [[ -w "$socketFile" ]] && echo "$windowName" | socat - UNIX-CLIENT:"<#APPEND#>${socketFile}"'"'"
fi
# Load user defined settings
if [ [ -r ~/.ratpoison_customizations ] ] ; then
add_setting '# Load user defined settings'
add_setting " source ${ HOME } /.ratpoison_customizations "
fi
# Autostart section
add_setting $'\n' "# Autostart section"
if hash rpws & > /dev/null ; then
workspaces = " $( rangebox "Number of workspaces:" 1 8 4) "
if [ $workspaces -gt 1 ] ; then
add_setting exec /usr/bin/rpws init $workspaces -a
for i in $( seq $workspaces ) ; do
add_alias alias go_to_workspace_$i exec rpws $i
add_alias alias move_current_application_to_workspace_$i rpwsm$i
add_setting definekey top C-F$i go_to_workspace_$i
add_setting definekey top C-S-F$i move_current_application_to_workspace_$i
done
fi
fi
if command -v transfersh & > /dev/null ; then
add_setting bind u transfer_file
add_alias alias transfer_file 'exec fileName="$(yad --title "Strychnine Upload File" --file)" && url="$(transfersh "${fileName}" | tee >(yad --title "Strychnine - Uploading ${fileName##*/} ..." --progress --pulsate --no-buttons --auto-close))" && echo "${url#*saved at: }" | tee >(yad --title "Strychnine - Upload URL" --show-cursor --show-uri --button yad-close --sticky --text-info) >(xclip -selection clipboard)'
fi
# Additional startup programs
if [ -n " $( find /usr -type f -name 'notification-daemon' 2> /dev/null) " ] ; then
add_setting " exec $( find /usr -type f -name 'notification-daemon' 2> /dev/null) "
fi
unset programs
brlapi = " $( yesno "Do you want to use a braille display with Orca?" ) "
if [ [ " $brlapi " = = "yes" ] ] ; then
programs += ( " $( command -v xbrlapi) --quiet " )
fi
if command -v clipster & > /dev/null ; then
programs += ( " $( command -v clipster) -d " )
add_setting definekey top M-C-c exec clipster -s
fi
echo "Enter any programs you want started automatically one per line. Press enter on a blank line when you are finished." | fold -s -w $( tput cols)
read -p "Enter program or enter when done: " -e programName
while [ [ -n " ${ programName } " ] ] ; do
programs += ( " ${ programName } " )
read -p "Enter program or enter when done: " -e programName
done
if [ [ -n " $programs " ] ] ; then
for i in " ${ programs [@] } " ; do
add_setting exec " $i "
done
fi
add_setting exec 'if [ "$(gsettings get org.gnome.desktop.a11y.applications screen-reader-enabled)" != "true" ]; then gsettings set org.gnome.desktop.a11y.applications screen-reader-enabled true&&' " $notify \"QT5 accessibility enabled. You need to restart ratpoison for the changes to take affect.\" " ';fi'
add_setting exec /usr/bin/orca
if [ -f " $HOME /.ratpoisonrc " ] ; then
continue = " $( yesno " $HOME /.ratpoisonrc exists. Over write it? " ) "
if [ " $continue " = "no" ] ; then
exit 0
fi
fi
echo " $rc " > $HOME /.ratpoisonrc
echo >> $HOME /.ratpoisonrc
echo "# Alias Section" >> $HOME /.ratpoisonrc
echo " $rpAlias " >> $HOME /.ratpoisonrc
exit 0