Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
278ee7a581 | |||
1b031229a7 | |||
e86f2d01f6 | |||
07ed90d4fc | |||
65e8c0636a | |||
2e15449d9a | |||
8e9c2c8a7d | |||
9b539d48ab | |||
aae01bff20 | |||
ef882604af | |||
eb8fa44757 | |||
6063fac699 | |||
6f8b418e80 | |||
239d110f58 | |||
b24c0fad91 | |||
00a89467fd | |||
9c3cadd7dc | |||
43bec02a2c | |||
a7746d962c | |||
0727ff31c3 | |||
482d8ebed2 | |||
df4182b32f | |||
ef030f9cd1 | |||
e484405684 | |||
4d5abd5489 | |||
cff7288c9e | |||
b1f413660f | |||
1a0ad68ad2 | |||
556b8cb7d8 | |||
563e0277aa | |||
4e00211c02 | |||
e61d0394c3 | |||
af77a60355 | |||
80cb28dc10 | |||
2968bbe325 | |||
15bf470616 | |||
19d201ecf4 | |||
cb7bfb36e8 | |||
9c16367299 | |||
68620696fc | |||
43067c0efe | |||
4773bdae87 | |||
ea7450bb8b | |||
50f7bd809a | |||
1de8cde4cf | |||
7ee783edeb | |||
9c1ac5f7f3 | |||
dca451c996 | |||
61cdfffc0d | |||
5851aec8b3 | |||
8b30abc8b6 |
37
README.md
37
README.md
@ -15,24 +15,57 @@ An uppercase I looks like a 1, 3 from i3, and 8 because the song [We Are 138](ht
|
||||
## Requirements
|
||||
|
||||
- i3-wm: The i3 window manager.
|
||||
- acpi: [optional] for battery status. It will still work even without this package, but uses it if it is installed.
|
||||
- acpi: [optional] for battery status. It will still work even without this package, but uses it if it is installed. Required for the battery monitor with sound alerts.
|
||||
- dex: [optional] Alternative method for auto starting applications.
|
||||
- clipster: clipboard manager
|
||||
- jq: for getting the current workspace
|
||||
- libcanberra: [optional]To play the desktop login sound.
|
||||
- libnotify: For sending notifications
|
||||
- notification-daemon: To handle notifications
|
||||
- ocrdesktop: For getting contents of the current window with OCR.
|
||||
- pamixer: for the mute-unmute script
|
||||
- playerctl: music controls
|
||||
- python-i3ipc: for sounds etc.
|
||||
- remind: [optional]For reminder notifications, Requires notify-daemon and notify-send for automatic reminders.
|
||||
- sgtk-menu: for applications menu
|
||||
- sox: for sounds.
|
||||
- transfersh: [optional] for file sharing GUI
|
||||
- udiskie: [optional] for automatically mounting removable storage
|
||||
- xclip: Clipboard support
|
||||
- xbacklight: [optional] for screen brightness adjustment
|
||||
- xorg-setxkbmap: [optional] for multiple keyboard layouts
|
||||
- yad: For screen reader accessible dialogs
|
||||
|
||||
I38 will try to detect your browser, file manager, and web browser and present you with a list of options to bind to their launch keys. It will also create bindings for pidgin and mumble if they are installed. To use the bindings, press your ratpoison mode key which is set when you run the i38.sh script. next, press the binding for the application you want, w for web browser, e for text editor, f for file manager, m for mumble, etc. To learn all the bindings, find and read the mode ratpoison section of ~/.config/i3/config.
|
||||
I38 will try to detect your browser, file manager, and web browser and present you with a list of options to bind to their launch keys. It will also create bindings for pidgin and mumble if they are installed. To use the bindings, press your ratpoison mode key which is set when you run the i38.sh script. next, press the binding for the application you want; w for web browser, e for text editor, f for file manager, m for mumble, etc. To learn all the bindings, find and read the mode ratpoison section of ~/.config/i3/config.
|
||||
|
||||
The login sound uses the GTK sound theme. Configure this using GTK configuration files or gsettings. Replace "name" with the name of the theme you want to use.
|
||||
|
||||
Note that if you enable all sound events as shown below, you'll also hear GTK sounds when moving around menus, buttons, etc, if the sound theme has sounds for those events.
|
||||
|
||||
To configure the theme name with gsettings, do as follows.
|
||||
|
||||
gsettings set org.gnome.desktop.sound theme-name name
|
||||
|
||||
If you'd like all sound types enabled:
|
||||
|
||||
gsettings set org.gnome.desktop.sound input-feedback-sounds true
|
||||
|
||||
gsettings set org.gnome.desktop.sound event-sounds true
|
||||
|
||||
To configure with a config file, edit or create ~/.config/gtk-3.0/settings.ini
|
||||
|
||||
[Settings]
|
||||
gtk-enable-event-sounds=1
|
||||
gtk-enable-input-feedback-sounds=1
|
||||
gtk-sound-theme-name=name
|
||||
gtk-modules=canberra-gtk-module
|
||||
|
||||
You can apply the same configuration to GTK2 appss. Create or edit ~/.gtkrc-2.0
|
||||
|
||||
gtk-enable-event-sounds=1
|
||||
gtk-enable-input-feedback-sounds=1
|
||||
gtk-sound-theme-name=name
|
||||
gtk-modules=canberra-gtk-module
|
||||
|
||||
## Usage:
|
||||
|
||||
|
199
i38.sh
199
i38.sh
@ -6,6 +6,7 @@
|
||||
|
||||
i3Path="${XDG_CONFIG_HOME:-$HOME/.config}/i3"
|
||||
i3msg="i3-msg"
|
||||
sensibleTerminal="i3-sensible-terminal"
|
||||
# Dialog accessibility
|
||||
export DIALOGOPTS='--no-lines --visit-items'
|
||||
|
||||
@ -24,6 +25,110 @@ if [[ -n "${missing}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
keyboard_menu() {
|
||||
keyboardMenu=("us" "English (US)"
|
||||
"af" "Dari"
|
||||
"al" "Albanian"
|
||||
"et" "Amharic"
|
||||
"ara" "Arabic"
|
||||
"ma" "Arabic (Morocco)"
|
||||
"sy" "Arabic (Syria)"
|
||||
"am" "Armenian"
|
||||
"az" "Azerbaijani"
|
||||
"ml" "Bambara"
|
||||
"bd" "Bangla"
|
||||
"by" "Belarusian"
|
||||
"be" "Belgian"
|
||||
"dz" "Berber (Algeria, Latin)"
|
||||
"ba" "Bosnian"
|
||||
"brai" "Braille"
|
||||
"bg" "Bulgarian"
|
||||
"mm" "Burmese"
|
||||
"cn" "Chinese"
|
||||
"hr" "Croatian"
|
||||
"cz" "Czech"
|
||||
"dk" "Danish"
|
||||
"mv" "Dhivehi"
|
||||
"nl" "Dutch"
|
||||
"bt" "Dzongkha"
|
||||
"au" "English (Australia)"
|
||||
"gh" "English (Ghana)"
|
||||
"ng" "English (Nigeria)"
|
||||
"za" "English (South Africa)"
|
||||
"gb" "English (UK)"
|
||||
"epo" "Esperanto"
|
||||
"ee" "Estonian"
|
||||
"fo" "Faroese"
|
||||
"ph" "Filipino"
|
||||
"fi" "Finnish"
|
||||
"fr" "French"
|
||||
"ca" "French (Canada)"
|
||||
"cd" "French (Democratic Republic of the Congo)"
|
||||
"ge" "Georgian"
|
||||
"de" "German"
|
||||
"ch" "German (Switzerland)"
|
||||
"gr" "Greek"
|
||||
"il" "Hebrew"
|
||||
"hu" "Hungarian"
|
||||
"is" "Icelandic"
|
||||
"in" "Indian"
|
||||
"jv" "Indonesian (Javanese)"
|
||||
"iq" "Iraqi"
|
||||
"ie" "Irish"
|
||||
"it" "Italian"
|
||||
"jp" "Japanese"
|
||||
"nec_vndr/jp" "Japanese (PC-98)"
|
||||
"kz" "Kazakh"
|
||||
"kh" "Khmer (Cambodia)"
|
||||
"kr" "Korean"
|
||||
"kg" "Kyrgyz"
|
||||
"la" "Lao"
|
||||
"lv" "Latvian"
|
||||
"lt" "Lithuanian"
|
||||
"mk" "Macedonian"
|
||||
"mv" "Malay (Jawi, Arabic Keyboard)"
|
||||
"mt" "Maltese"
|
||||
"mao" "Maori"
|
||||
"mn" "Mongolian"
|
||||
"me" "Montenegrin"
|
||||
"gn" "N'Ko (AZERTY)"
|
||||
"np" "Nepali"
|
||||
"no" "Norwegian"
|
||||
"ir" "Persian"
|
||||
"pl" "Polish"
|
||||
"pt" "Portuguese"
|
||||
"br" "Portuguese (Brazil)"
|
||||
"ro" "Romanian"
|
||||
"ru" "Russian"
|
||||
"rs" "Serbian"
|
||||
"lk" "Sinhala (phonetic)"
|
||||
"sk" "Slovak"
|
||||
"si" "Slovenian"
|
||||
"es" "Spanish"
|
||||
"latam" "Spanish (Latin American)"
|
||||
"tz" "Swahili (Tanzania)"
|
||||
"se" "Swedish"
|
||||
"tw" "Taiwanese"
|
||||
"tj" "Tajik"
|
||||
"th" "Thai"
|
||||
"tr" "Turkish"
|
||||
"tm" "Turkmen"
|
||||
"bw" "Tswana"
|
||||
"ua" "Ukrainian"
|
||||
"pk" "Urdu (Pakistan)"
|
||||
"uz" "Uzbek (Afghanistan)"
|
||||
"vn" "Vietnamese"
|
||||
"sn" "Wolof"
|
||||
)
|
||||
dialog --title "I38" \
|
||||
--backtitle "Use the arrow keys to find the option you want, and enter to select it. When you are finished selecting layouts, use right arrow to find \"Done\" and press enter." \
|
||||
--clear \
|
||||
--cancel-label "Done" \
|
||||
--no-tags \
|
||||
--menu "Select Keyboard Layout" 0 0 0 "${keyboardMenu[@]}" --stdout
|
||||
return $?
|
||||
}
|
||||
|
||||
menulist() {
|
||||
# Args: List of items for menu.
|
||||
# returns: selected tag
|
||||
@ -37,7 +142,7 @@ menulist() {
|
||||
--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
|
||||
--menu "$menuText" 0 0 0 "${menuList[@]}" --stdout
|
||||
return $?
|
||||
}
|
||||
|
||||
@ -147,6 +252,7 @@ while getopts "${args}" i ; do
|
||||
s)
|
||||
i3msg="swaymsg"
|
||||
i3Path="${XDG_CONFIG_HOME:-$HOME/.config}/sway"
|
||||
sensibleTerminal="sway --sensible-terminal"
|
||||
;;
|
||||
u) update_scripts;;
|
||||
x) write_xinitrc ;&
|
||||
@ -170,11 +276,35 @@ while [[ "$escapeKey" == "$mod" ]]; do
|
||||
dialog --title "I38" --msgbox "Ratpoison and mod key cannot be the same key." -1 -1
|
||||
fi
|
||||
done
|
||||
# Multiple keyboard layouts
|
||||
if [[ $(yesno "Do you want to use multiple keyboard layouts?") -eq 0 ]]; then
|
||||
unset kbd
|
||||
while : ; do
|
||||
kbd+=("$(keyboard_menu)") || break
|
||||
done
|
||||
fi
|
||||
# Volume jump
|
||||
volumeJump=$(rangebox "How much should pressing the volume keys change the volume?" 1 15 5)
|
||||
# Email client
|
||||
unset programList
|
||||
for i in betterbird evolution thunderbird ; do
|
||||
if command -v ${i/#-/} &> /dev/null ; then
|
||||
if [ -n "$programList" ]; then
|
||||
programList="$programList $i"
|
||||
else
|
||||
programList="$i"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "$programList" != "${programList// /}" ]; then
|
||||
emailClient="$(menulist "Email client:" $programList)"
|
||||
else
|
||||
emailClient="${programList/#-/}"
|
||||
fi
|
||||
emailClient="$(command -v $emailClient)"
|
||||
# Web browser
|
||||
unset programList
|
||||
for i in brave chromium epiphany firefox google-chrome-stable midori seamonkey ; do
|
||||
for i in brave chromium epiphany firefox google-chrome-stable microsoft-edge microsoft-edge-beta microsoft-edge-dev midori seamonkey ; do
|
||||
if command -v ${i/#-/} &> /dev/null ; then
|
||||
if [ -n "$programList" ]; then
|
||||
programList="$programList $i"
|
||||
@ -224,6 +354,11 @@ else
|
||||
fileBrowser="${programList/#-/}"
|
||||
fi
|
||||
fileBrowser="$(command -v $fileBrowser)"
|
||||
# Auto mount removable media
|
||||
udiskie=1
|
||||
if command -v udiskie &> /dev/null ; then
|
||||
export udiskie=$(yesno "Would you like removable drives to automatically mount when plugged in?")
|
||||
fi
|
||||
# Auto start with dex
|
||||
dex=1
|
||||
if command -v dex &> /dev/null ; then
|
||||
@ -232,10 +367,19 @@ fi
|
||||
if [[ $dex -eq 0 ]]; then
|
||||
dex -t "${XDG_CONFIG_HOME:-${HOME}/.config}/autostart" -c $(command -v orca)
|
||||
fi
|
||||
if command -v acpi &> /dev/null ; then
|
||||
batteryAlert=1
|
||||
batteryAlert=$(yesno "Do you want low battery notifications?")
|
||||
fi
|
||||
brlapi=1
|
||||
brlapi=$(yesno "Do you want to use a braille display with Orca?")
|
||||
sounds=1
|
||||
sounds=$(yesno "Do you want window event sounds?")
|
||||
# Play Login Sound
|
||||
loginSound=1
|
||||
if command -v canberra-gtk-play &> /dev/null ; then
|
||||
export loginSound=$(yesno "Would you like to play the default desktop-login sound according to your GTK sound theme upon login?")
|
||||
fi
|
||||
|
||||
if [[ -d "${i3Path}" ]]; then
|
||||
yesno "This will replace your existing configuration at ${i3Path}. Do you want to continue?" || exit 0
|
||||
@ -248,7 +392,7 @@ mkdir -p "${i3Path}"
|
||||
cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Moving scripts into place and writing config..." -1 -1
|
||||
|
||||
cat << EOF > ${i3Path}/config
|
||||
# Generated by I38 (${0##*/}) https://github.com/stormdragon2976/I38
|
||||
# Generated by I38 (${0##*/}) https://git.stormux.org/storm/I38
|
||||
# $(date '+%A, %B %d, %Y at %I:%M%p')
|
||||
|
||||
|
||||
@ -302,7 +446,7 @@ bindsym XF86AudioStop exec --no-startup-id play -qV0 "| sox -np synth 0.03 sin 2
|
||||
bindsym XF86AudioNext exec --no-startup-id play -qV0 "| sox -np synth 0.03 sin 2000 pad 0 .02" "| sox -np synth 0.03 sin 2000" norm 1.0 vol 0.4 & ${i3Path}/scripts/music_controler.sh next
|
||||
|
||||
# start a terminal
|
||||
bindsym \$mod+Return exec i3-sensible-terminal
|
||||
bindsym \$mod+Return exec $sensibleTerminal
|
||||
|
||||
# kill focused window
|
||||
bindsym \$mod+F4 kill
|
||||
@ -367,8 +511,22 @@ bindsym Control+Shift+F9 move container to workspace number \$ws9, exec spd-say
|
||||
bindsym Control+Shift+F10 move container to workspace number \$ws10, exec spd-say -P important -Cw "moved to workspace 10"
|
||||
|
||||
|
||||
# A mode that will pass all keys except $mod+shift+backspace to the current application.
|
||||
# Use $mod+shift+backspace to exit the mode.
|
||||
bindsym $mod+shift+BackSpace mode "bypass"
|
||||
mode "bypass" {
|
||||
# Exit bypass mode.
|
||||
bindsym $mod+Shift+BackSpace mode "default"
|
||||
}
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
# Multiple keyboard layouts if requested.
|
||||
if [[ ${#kbd[@]} -gt 1 ]]; then
|
||||
echo "bindsym Mod4+space exec ${i3Path}/scripts/keyboard.sh cycle ${kbd[@]}" >> ${i3Path}/config
|
||||
fi
|
||||
|
||||
# Create ratpoison mode if requested.
|
||||
if [[ -n "${escapeKey}" ]]; then
|
||||
cat << EOF >> ${i3Path}/config
|
||||
@ -377,11 +535,15 @@ mode "ratpoison" {
|
||||
# I38 help bound to ?
|
||||
bindsym Shift+slash exec ${i3Path}/scripts/i38-help.sh, mode "default"
|
||||
# Terminal emulator bound to c
|
||||
bindsym c exec i3-sensible-terminal, mode "default"
|
||||
bindsym c exec $sensibleTerminal, mode "default"
|
||||
# Text editor bound to e
|
||||
bindsym e exec $textEditor, mode "default"
|
||||
# File browser bound to f
|
||||
bindsym f exec $fileBrowser, mode "default"
|
||||
$(if [[ ${#fileBrowser} -gt 3 ]]; then
|
||||
echo "# File browser bound to f"
|
||||
echo "bindsym f exec $fileBrowser, mode \"default\""
|
||||
fi)
|
||||
# Email client bound to \$mod+e
|
||||
bindsym \$mod+e exec $emailClient, mode "default"
|
||||
# Web browser bound to w
|
||||
bindsym w exec $webBrowser, mode "default"
|
||||
# Kill window bound to k
|
||||
@ -390,6 +552,10 @@ $(if command -v mumble &> /dev/null ; then
|
||||
echo "# Mumble bound to m"
|
||||
echo "bindsym m exec $(command -v mumble), mode \"default\""
|
||||
fi)
|
||||
$(if command -v remind &> /dev/null ; then
|
||||
echo "# Reminders bound to r"
|
||||
echo "bindsym r exec --no-startup-id ${i3Path}/scripts/reminder.sh, mode \"default\""
|
||||
fi)
|
||||
$(if command -v ocrdesktop &> /dev/null ; then
|
||||
echo "# OCR desktop bound to print screen alternative \$mod+r"
|
||||
echo "bindsym Print exec $(command -v ocrdesktop) -b, mode \"default\""
|
||||
@ -399,6 +565,10 @@ $(if command -v pidgin &> /dev/null ; then
|
||||
echo "# p bound to pidgin"
|
||||
echo "bindsym p exec $(command -v pidgin), mode \"default\""
|
||||
fi)
|
||||
$(if command -v xrandr &> /dev/null ; then
|
||||
echo "# alt+s bound to brightness control"
|
||||
echo "bindsym \$mod+s exec --no-startup-id ${i3Path}/scripts/screen_controller.sh, mode \"default\""
|
||||
fi)
|
||||
$(if command -v transfersh &> /dev/null ; then
|
||||
echo "# t bound to share file with transfer.sh"
|
||||
echo 'bindsym t exec bash -c '"'"'fileName="$(yad --title "I38 Upload File" --file)" && url="$(transfersh "${fileName}" | tee >(yad --title "I38 - Uploading ${fileName##*/} ..." --progress --pulsate --auto-close))" && echo "${url#*saved at: }" | tee >(yad --title "I38 - Upload URL" --show-cursor --show-uri --button yad-close --sticky --text-info) >(xclip -selection clipboard)'"', mode \"default\""
|
||||
@ -428,7 +598,7 @@ bindsym Shift+o exec $(command -v orca) --replace, mode "default"
|
||||
# reload the configuration file
|
||||
bindsym Control+semicolon exec bash -c '$i3msg -t run_command reload && spd-say -P important -Cw "I38 Configuration reloaded."', mode "default"
|
||||
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
|
||||
bindsym Control+Shift+semicolon exec bash -c '$i3msg -t run_command restart && spd-say -P important -Cw "I3 restarted."', mode "default"
|
||||
bindsym Control+Shift+semicolon exec bash -c 'killall remind || true && $i3msg -t run_command restart && spd-say -P important -Cw "I3 restarted."', mode "default"
|
||||
# Run dialog with exclamation
|
||||
bindsym Shift+exclam exec ${i3Path}/scripts/run_dialog.sh, mode "default"
|
||||
# exit i3 (logs you out of your X session)
|
||||
@ -448,9 +618,15 @@ cat << EOF >> ${i3Path}/config
|
||||
$(if [[ $sounds -eq 0 ]]; then
|
||||
echo "exec_always --no-startup-id ${i3Path}/scripts/sound.py"
|
||||
fi
|
||||
if [[ $loginSound -eq 0 ]]; then
|
||||
echo 'exec --no-startup-id canberra-gtk-play -i desktop-login'
|
||||
fi
|
||||
if [[ $brlapi -eq 0 ]]; then
|
||||
echo 'exec --no-startup-id xbrlapi --quiet'
|
||||
fi
|
||||
if [[ $udiskie -eq 0 ]]; then
|
||||
echo 'exec --no-startup-id udiskie'
|
||||
fi
|
||||
if [[ -x "/usr/lib/notification-daemon-1.0/notification-daemon" ]]; then
|
||||
echo 'exec_always --no-startup-id /usr/lib/notification-daemon-1.0/notification-daemon -r'
|
||||
fi
|
||||
@ -458,6 +634,13 @@ fi
|
||||
if [[ -x "/usr/libexec/notification-daemon" ]]; then
|
||||
echo 'exec_always --no-startup-id /usr/libexec/notification-daemon -r'
|
||||
fi
|
||||
if command -v remind &> /dev/null && command -v notify-send &> /dev/null ; then
|
||||
echo "exec_always --no-startup-id $(command -v remind) -z '-k:${HOME}/.config/i3/scripts/reminder.sh %s &' ${HOME}/.reminders < /dev/null > /dev/null 2>&1"
|
||||
touch ~/.reminders
|
||||
fi
|
||||
if [[ $batteryAlert -eq 0 ]]; then
|
||||
echo "exec_always --no-startup-id ${i3Path}/scripts/battery_alert.sh"
|
||||
fi
|
||||
if [[ $dex -eq 0 ]]; then
|
||||
echo '# Start XDG autostart .desktop files using dex. See also'
|
||||
echo '# https://wiki.archlinux.org/index.php/XDG_Autostart'
|
||||
|
@ -1,8 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
workSpace="$(i3-msg -t get_workspaces \
|
||||
| jq '.[] | select(.focused==true).name' \
|
||||
| cut -d"\"" -f2)"
|
||||
path="$(readlink -f $0)"
|
||||
path="${path%/*/*}"
|
||||
path="${path##*/}"
|
||||
if [[ "$path" == "i3" ]]; then
|
||||
workSpace="$(i3-msg -t get_workspaces \
|
||||
| jq '.[] | select(.focused==true).name' \
|
||||
| cut -d"\"" -f2)"
|
||||
else
|
||||
workSpace="$(swaymsg -t get_workspaces \
|
||||
| jq '.[] | select(.focused==true).name' \
|
||||
| cut -d"\"" -f2)"
|
||||
fi
|
||||
left=9
|
||||
right=0
|
||||
msg="Workspace ${workSpace}"
|
||||
|
25
scripts/battery_alert.sh
Executable file
25
scripts/battery_alert.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! command -v acpi &> /dev/null ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while : ; do
|
||||
acpi -b | awk -F'[,:%]' '{print $2, $3}' | {
|
||||
read -r status capacity
|
||||
|
||||
if [[ "$status" == "Discharging" ]] && [[ "$capacity" -le 15 ]] && [[ "$capacity" -gt 10 ]]; then
|
||||
play -qV0 "|sox -n -p synth saw E2 fade 0 0.25 0.05" "|sox -n -p synth saw E2 fade 0 0.25 0.05" norm -7
|
||||
spd-say -P important "Battery $capacity percent."
|
||||
elif [[ "$status" == "Discharging" ]] && [[ "$capacity" -le 10 ]] && [[ "$capacity" -gt 5 ]]; then
|
||||
play -qV0 "|sox -n -p synth saw E2 fade 0 0.25 0.05" "|sox -n -p synth saw E2 fade 0 0.25 0.05" norm -7
|
||||
spd-say -P important "Battery $capacity percent."
|
||||
elif [[ "$status" == "Discharging" ]] && [[ "$capacity" -lt 5 ]]; then
|
||||
play -qV0 "|sox -np synth sq C#5 sq D#5 sq F#5 sq A5 sq C#6" remix - fade 0 5.5 5 pitch -400
|
||||
spd-say -P important "Battery $capacity percent."
|
||||
fi
|
||||
}
|
||||
sleep 5m
|
||||
done
|
||||
|
||||
exit 0
|
48
scripts/keyboard.sh
Executable file
48
scripts/keyboard.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# This script is a modified version of i3-keyboard-layout.
|
||||
# Originally Copyright (c) 2018 Sergio Gil.
|
||||
# https://github.com/porras/i3-keyboard-layout
|
||||
# This modified script, like the rest of I38, is released under the WTFPL license.
|
||||
# The original work was released under the MIT license.
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
get_kbdlayout() {
|
||||
layout=$(setxkbmap -query | grep -oP 'layout:\s*\K([\w,]+)')
|
||||
variant=$(setxkbmap -query | grep -oP 'variant:\s*\K(\w+)')
|
||||
echo "$layout" "$variant"
|
||||
}
|
||||
|
||||
set_kbdlayout() {
|
||||
eval "array=($1)"
|
||||
setxkbmap "${array[@]}" &&
|
||||
spd-say -P important -Cw "${array[@]}"
|
||||
}
|
||||
|
||||
cycle() {
|
||||
current_layout=$(get_kbdlayout | xargs)
|
||||
layouts=("$@" "$1") # add the first one at the end so that it cycles
|
||||
index=0
|
||||
while [ "${layouts[$index]}" != "$current_layout" ] && [ $index -lt "${#layouts[@]}" ]; do index=$[index +1]; done
|
||||
next_index=$[index +1]
|
||||
next_layout=${layouts[$next_index]}
|
||||
set_kbdlayout "$next_layout"
|
||||
}
|
||||
|
||||
|
||||
subcommand="$1"
|
||||
shift || exit 1
|
||||
|
||||
case $subcommand in
|
||||
"get")
|
||||
echo -n $(get_kbdlayout)
|
||||
;;
|
||||
"cycle")
|
||||
cycle "$@"
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
376
scripts/reminder.sh
Executable file
376
scripts/reminder.sh
Executable file
@ -0,0 +1,376 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
error() {
|
||||
yad --form --selectable-labels --title "I38 - Reminder Error" --field="${*}":lbl --button="Close!gtk-ok":0
|
||||
}
|
||||
|
||||
message() {
|
||||
yad --form --selectable-labels --title "I38 - Reminder" --field="${*}":lbl --button="Close!gtk-ok":0
|
||||
}
|
||||
|
||||
|
||||
add_reminder() {
|
||||
info="$(yad --form --selectable-labels \
|
||||
--title "I38 - New Reminder" \
|
||||
--field="Comment for ~/.reminders file":lbl "" \
|
||||
--field="Reminder Comment" "# Added by I38" \
|
||||
--field="Enter date in yyyy-mm-dd format:":lbl "" \
|
||||
--field="Date" "$(date '+%Y-%m-%d')" \
|
||||
--field="Reminder text:":lbl "" \
|
||||
--field="Reminder" "" \
|
||||
--field="Select Hour:":num '1!1..12' \
|
||||
--field="Select Minute:":num '0!0..59' \
|
||||
--field="Select AM or PM":cb 'AM!PM' \
|
||||
--button="Cancel!gtk-cancel:1" \
|
||||
--button="Create Reminder!gtk-ok:0")"
|
||||
if [[ $? -eq 1 || $? -eq 252 ]]; then
|
||||
return
|
||||
fi
|
||||
while [[ $info =~ \|\| ]]; do
|
||||
info="${info//||/|}"
|
||||
done
|
||||
info="${info#|#}"
|
||||
# Get information for reminder into an array
|
||||
IFS='|' read -a reminder <<< $info
|
||||
# Fix time to be 2 digits.
|
||||
[[ ${#reminder[3]} -eq 1 ]] && reminder[3]="0${reminder[3]}"
|
||||
[[ ${#reminder[4]} -eq 1 ]] && reminder[4]="0${reminder[4]}"
|
||||
# Check date format
|
||||
if ! [[ "${reminder[1]}" =~ ^[2-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$ ]]; then
|
||||
error "Invalid date format given, addition canceled."
|
||||
return
|
||||
fi
|
||||
if [[ ${#reminder[2]} -lt 3 ]]; then
|
||||
error "No reminder text given, addition canceled."
|
||||
return
|
||||
fi
|
||||
# Add reminder
|
||||
if [[ "${reminder[0]}" != "# " ]]; then
|
||||
echo "# ${reminder[0]}" >> ~/.reminders
|
||||
fi
|
||||
echo "REM $(date -d "${reminder[1]}" '+%b %d %Y') AT ${reminder[3]}:${reminder[4]}${reminder[5]} +5 MSG ${reminder[2]} %2." >> ~/.reminders
|
||||
if [[ -N ~/.reminders ]]; then
|
||||
message "Reminder added."
|
||||
else
|
||||
error "Something went wrong. The reminder was not added."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
add_custom_reminder() {
|
||||
info="$(yad --form --selectable-labels \
|
||||
--title "I38 - New Custom Reminder" \
|
||||
--field="Comment for ~/.reminders file":lbl "" \
|
||||
--field="Reminder Comment" "" \
|
||||
--field="Reminder entry. Remember for notifications, it must ccontain the +5 after the time and the %2. at the end of the MSG.":lbl "" \
|
||||
--field="Reminder" "REM at +5 MSG %2.")"
|
||||
if [[ $? -eq 1 || $? -eq 252 ]]; then
|
||||
return
|
||||
fi
|
||||
while [[ $info =~ \|\| ]]; do
|
||||
info="${info//||/|}"
|
||||
done
|
||||
info="${info#|#}"
|
||||
# Get information for reminder into an array
|
||||
IFS='|' read -a reminder <<< $info
|
||||
if [[ "${reminder[0]}" != "# " ]]; then
|
||||
echo "# ${reminder[0]}" >> ~/.reminders
|
||||
fi
|
||||
if [[ "${reminder[1]}" != "REM at +5 MSG %2." ]]; then
|
||||
echo "${reminder[1]}" >> ~/.reminders
|
||||
message "Custom reminder added."
|
||||
else
|
||||
error "No reminder text entered, No action taken."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
add_daily_reminder() {
|
||||
info="$(yad --form --selectable-labels \
|
||||
--title "I38 - New Daily Reminder" \
|
||||
--field="Reminder Text" "" \
|
||||
--field="Select Hour:":num '1!1..12' \
|
||||
--field="Select Minute:":num '0!0..59' \
|
||||
--field="Select AM or PM":cb 'AM!PM' \
|
||||
--button="Cancel!gtk-cancel:1" \
|
||||
--button="Create Reminder!gtk-ok:0")"
|
||||
|
||||
# Properly handle window close events.
|
||||
if [[ $? -eq 1 || $? -eq 252 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Get information for reminder into an array
|
||||
IFS='|' read -a reminder <<< $info
|
||||
|
||||
# Fix time to be 2 digits.
|
||||
[[ ${#reminder[1]} -eq 1 ]] && reminder[1]="0${reminder[1]}"
|
||||
[[ ${#reminder[2]} -eq 1 ]] && reminder[2]="0${reminder[2]}"
|
||||
|
||||
# Make sure we have reminder text
|
||||
if [[ ${#reminder[0]} -lt 3 ]]; then
|
||||
error "No reminder text given, addition canceled."
|
||||
return
|
||||
fi
|
||||
reminderEntry="REM AT ${reminder[1]}:${reminder[2]}${reminder[3]} +5 REPEAT daily MSG ${reminder[0]} %2."
|
||||
echo "# Added by I38." >> ~/.reminders
|
||||
echo "$reminderEntry" >> ~/.reminders
|
||||
if [[ -N ~/.reminders ]]; then
|
||||
message "Reminder added."
|
||||
else
|
||||
error "Something went wrong. The reminder was not added."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
add_monthly_reminder() {
|
||||
info="$(yad --form --selectable-labels \
|
||||
--title "I38 - New Monthly Reminder" \
|
||||
--field="For dates over 28, some months may be skipped. If you want to be sure of the last day of the month, check the last day of month box.":lbl "" \
|
||||
--field="Reminder Text" "" \
|
||||
--field="Select Date:":num '1!1..31' \
|
||||
--field="Select Hour:":num '1!1..12' \
|
||||
--field="Select Minute:":num '0!0..59' \
|
||||
--field="Select AM or PM":cb 'AM!PM' \
|
||||
--field="Last day of month":chk "FALSE" \
|
||||
--button="Cancel!gtk-cancel:1" \
|
||||
--button="Create Reminder!gtk-ok:0")"
|
||||
|
||||
# Properly handle window close events.
|
||||
if [[ $? -eq 1 || $? -eq 252 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Get information for reminder into an array
|
||||
IFS='|' read -a reminder <<< $info
|
||||
|
||||
# Fix time and date to be 2 digits.
|
||||
[[ ${#reminder[2]} -eq 1 ]] && reminder[2]="0${reminder[2]}"
|
||||
[[ ${#reminder[3]} -eq 1 ]] && reminder[3]="0${reminder[3]}"
|
||||
[[ ${#reminder[4]} -eq 1 ]] && reminder[4]="0${reminder[4]}"
|
||||
|
||||
# Make sure we have reminder text
|
||||
if [[ ${#reminder[1]} -lt 3 ]]; then
|
||||
error "No reminder text given, addition canceled."
|
||||
return
|
||||
fi
|
||||
if [[ "${reminder[6]}" == "FALSE" ]]; then
|
||||
reminderEntry="REM ${reminder[2]} "
|
||||
else
|
||||
reminderEntry="REM 1 -1 "
|
||||
fi
|
||||
reminderEntry+="AT ${reminder[3]}:${reminder[4]}${reminder[5]} +5 REPEAT monthly MSG ${reminder[1]} %2."
|
||||
echo "# Added by I38." >> ~/.reminders
|
||||
echo "$reminderEntry" >> ~/.reminders
|
||||
if [[ -N ~/.reminders ]]; then
|
||||
message "Reminder added."
|
||||
else
|
||||
error "Something went wrong. The reminder was not added."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
add_weekly_reminder() {
|
||||
info="$(yad --form --selectable-labels \
|
||||
--title "I38 - New Weekly Reminder" \
|
||||
--field="Reminder Text" "" \
|
||||
--field="Select Days":lbl "" \
|
||||
--field="Sunday":chk "FALSE" \
|
||||
--field="Monday":chk "FALSE" \
|
||||
--field="Tuesday":chk "FALSE" \
|
||||
--field="Wednesday":chk "FALSE" \
|
||||
--field="Thursday":chk "FALSE" \
|
||||
--field="Friday":chk "FALSE" \
|
||||
--field="Saturday":chk "FALSE" \
|
||||
--field="Select Hour:":num '1!1..12' \
|
||||
--field="Select Minute:":num '0!0..59' \
|
||||
--field="Select AM or PM":cb 'AM!PM' \
|
||||
--button="Cancel!gtk-cancel:1" \
|
||||
--button="Create Reminder!gtk-ok:0")"
|
||||
|
||||
# Properly handle window close events.
|
||||
if [[ $? -eq 1 || $? -eq 252 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Get information for reminder into an array
|
||||
IFS='|' read -a reminder <<< $info
|
||||
|
||||
# Fix time to be 2 digits.
|
||||
[[ ${#reminder[9]} -eq 1 ]] && reminder[9]="0${reminder[9]}"
|
||||
[[ ${#reminder[10]} -eq 1 ]] && reminder[10]="0${reminder[10]}"
|
||||
|
||||
# Change checked days into their name.
|
||||
reminder[2]="${reminder[2]/TRUE/Sun}"
|
||||
reminder[3]="${reminder[3]/TRUE/Mon}"
|
||||
reminder[4]="${reminder[4]/TRUE/Tue}"
|
||||
reminder[5]="${reminder[5]/TRUE/Wed}"
|
||||
reminder[6]="${reminder[6]/TRUE/Thu}"
|
||||
reminder[7]="${reminder[7]/TRUE/Fri}"
|
||||
reminder[8]="${reminder[8]/TRUE/Sat}"
|
||||
|
||||
# Make sure we have reminder text
|
||||
if [[ ${#reminder[0]} -lt 3 ]]; then
|
||||
error "No reminder text given, addition canceled."
|
||||
return
|
||||
fi
|
||||
reminderEntry="REM "
|
||||
noDays=1
|
||||
for ((i=2;i<=8;i++)) ; do
|
||||
if [[ "${reminder[i]}" != "FALSE" ]]; then
|
||||
reminderEntry+="${reminder[i]} "
|
||||
noDays=0
|
||||
fi
|
||||
done
|
||||
if [[ $noDays -eq 1 ]]; then
|
||||
error "No days were selected for the reminder. Nothing changed."
|
||||
return
|
||||
fi
|
||||
reminderEntry+="AT ${reminder[9]}:${reminder[10]}${reminder[11]} +5 REPEAT weekly MSG ${reminder[0]} %2."
|
||||
echo "# Added by I38." >> ~/.reminders
|
||||
echo "$reminderEntry" >> ~/.reminders
|
||||
if [[ -N ~/.reminders ]]; then
|
||||
message "Reminder added."
|
||||
else
|
||||
error "Something went wrong. The reminder was not added."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
view_reminders() {
|
||||
if ! [[ -r ~/.reminders ]]; then
|
||||
error "No reminders found."
|
||||
return
|
||||
fi
|
||||
|
||||
mapfile -t lines < ~/.reminders
|
||||
# Create an empty array to store cleaned-up reminders
|
||||
yadMenu=()
|
||||
|
||||
# Iterate through the reminder lines and clean them up
|
||||
for i in "${lines[@]}"; do
|
||||
# Remove the "REM" prefix and leading/trailing spaces
|
||||
formattedLine="${i#*REM }"
|
||||
# Remove MSG from the output.
|
||||
formattedLine="${formattedLine/MSG /}"
|
||||
# remove the usually %2. from the end of the line, but accept any digit in case someone changes it.
|
||||
formattedLine="${formattedLine% %[[:digit:]].}"
|
||||
|
||||
# Add to the menu
|
||||
yadMenu+=("$formattedLine")
|
||||
done
|
||||
|
||||
# Display the reminders
|
||||
reminder="$(yad --list --title "I38 - Reminders" --text "Current reminders:" \
|
||||
--column "Reminder" "${yadMenu[@]}" \
|
||||
--button="Close!gtk-ok:1" --button="Delete!gtk-delete:0" --response=1)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ "${reminder:0:1}" == "#" ]]; then
|
||||
error "Please select the actual reminder to be deleted, anything starting with # is only a comment. Nothing changed."
|
||||
return
|
||||
fi
|
||||
# Remove the | from the end of reminder
|
||||
reminder="${reminder%|}"
|
||||
# Find the index to remove from lines.
|
||||
for i in "${!yadMenu[@]}" ; do
|
||||
if [[ "${yadMenu[i]}" == "${reminder}" ]]; then
|
||||
# Delete selected reminder and possible preceeding comment.
|
||||
commentIndex=$((i - 1))
|
||||
if [[ "${lines[commentIndex]:0:1}" == "#" ]]; then
|
||||
unset lines[$commentIndex]
|
||||
fi
|
||||
unset lines[$i]
|
||||
message "Reminder deleted."
|
||||
printf "%s\n" "${lines[@]}" > ~/.reminders
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
view_today() {
|
||||
if ! [[ -r ~/.reminders ]]; then
|
||||
error "No reminders found."
|
||||
return
|
||||
fi
|
||||
|
||||
mapfile -t lines < <(rem | tr -s $'\n')
|
||||
# Display the reminders
|
||||
yad --list --title "I38 - Reminders" --text "Today's reminders:" \
|
||||
--column "Reminder" "${lines[@]}" \
|
||||
--button="Close!gtk-ok:0"
|
||||
}
|
||||
|
||||
|
||||
if ! command -v remind &> /dev/null ; then
|
||||
error "Please install remind. For notifications, please make sure to have notification-daemon and notify-send as well. Run i38.sh to regenerate your i3 config after the needed components are installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $# -ne 0 ]]; then
|
||||
sox -ndqV0 synth .1 tri 600 norm -9 pad .05 repeat
|
||||
notification="$*"
|
||||
if [[ "${notification}" =~ "http" ]]; then
|
||||
url="${notification##*http}"
|
||||
url="${url%%[[:space:]]*}"
|
||||
url="http${url}"
|
||||
notification="${notification/${url}[[:space:]]/}"
|
||||
url="${url%[[:space:].?!]}"
|
||||
fi
|
||||
if command -v xclip &> /dev/null && [[ "${#url}" -gt 3 ]]; then
|
||||
echo "${url}" | xclip -selection clipboard
|
||||
notify-send --hint=int:transient:1 -t 500 -r 38 "${notification} The URL has been copied to the clipboard."
|
||||
else
|
||||
notify-send --hint=int:transient:1 -t 500 -r 38 "${*}"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while : ; do
|
||||
action=$(yad --title "I38 - Reminders" --form \
|
||||
--button="_View Today's Reminders!gtk-info":3 \
|
||||
--button="_View All Reminders!gtk-info":4 \
|
||||
--button="_Add Reminder!gtk-edit":0 \
|
||||
--button="_Add Daily Reminder!gtk-edit":2 \
|
||||
--button="_Add Weekly Reminder!gtk-edit":5 \
|
||||
--button="Add Monthly Reminder!gtk-edit":6 \
|
||||
--button="Add Custom Reminder!gtk-edit":7 \
|
||||
--button="Close!gtk-cancel":1 \
|
||||
--separator="")
|
||||
|
||||
case $? in
|
||||
0)
|
||||
# Single reminder
|
||||
add_reminder
|
||||
;;
|
||||
1|252)
|
||||
# Handle "Close" button click and escape.
|
||||
exit 0
|
||||
;;
|
||||
2)
|
||||
# Handle "Add Daily Reminder" button click
|
||||
add_daily_reminder
|
||||
;;
|
||||
3)
|
||||
# View today's reminders
|
||||
view_today
|
||||
;;
|
||||
4)
|
||||
# View reminders
|
||||
view_reminders
|
||||
;;
|
||||
5)
|
||||
# Handle "Add Weekly Reminder" button click
|
||||
add_weekly_reminder
|
||||
;;
|
||||
6)
|
||||
# Handle "Add Monthly Reminder" button click
|
||||
add_monthly_reminder
|
||||
;;
|
||||
7)
|
||||
# Handle "Add Custom Reminder" button click
|
||||
add_custom_reminder
|
||||
;;
|
||||
esac
|
||||
done
|
24
scripts/screen_controller.sh
Executable file
24
scripts/screen_controller.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Not for multiple screens.
|
||||
# Get the name of the screen.
|
||||
screenName="$(xrandr --query | grep "connected" | cut -d ' ' -f1 | head -n 1)"
|
||||
|
||||
menuOptions=(
|
||||
"1.0" "Maximum Brightness"
|
||||
"0.75" "75 percent"
|
||||
"0.5" "50 percent"
|
||||
"0.25" "25 percent"
|
||||
"0" "Screen Curtain"
|
||||
)
|
||||
|
||||
brightness="$(yad --list --title "I38" --text "Set Screen Brightness" --columns 2 --hide-column 1 --column "" --column "Select" "${menuOptions[@]}")"
|
||||
|
||||
if [[ ${#brightness} -lt 1 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
xrandr --output ${screenName} --brightness ${brightness%%|*} &&
|
||||
spd-say -P important -Cw "Screen set to ${brightness#*|}."
|
||||
|
||||
exit 0
|
@ -12,12 +12,19 @@ i3 = i3ipc.Connection()
|
||||
def on_new_window(self,i3):
|
||||
system('play -n synth .25 sin 440:880 sin 480:920 remix - norm -3 pitch -500 &')
|
||||
|
||||
def on_close_window(self,i3):
|
||||
system('play -n synth .25 sin 880:440 sin 920:480 remix - norm -3 pitch -500 &')
|
||||
|
||||
def on_mode(self,event):
|
||||
mode= event.change
|
||||
if mode == 'default':
|
||||
if mode == 'ratpoison':
|
||||
system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 &')
|
||||
elif mode == 'bypass':
|
||||
system('play -nqV0 synth .1 saw 700 saw 1200 delay 0 .04 remix - norm -6')
|
||||
elif mode == 'default':
|
||||
system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 reverse &')
|
||||
else:
|
||||
system('play -qV0 "|sox -np synth .07 sq 400" "|sox -np synth .5 sq 800" fade h 0 .5 .5 norm -20 &')
|
||||
system('play -n synth 0.05 pluck F3 norm -8 : synth 0.05 pluck C4 norm -8 : synth 0.05 pluck F4 norm -8 : synth 0.05 pluck C5 norm -8')
|
||||
|
||||
def on_workspace_focus(self,i3):
|
||||
#system('play -qnV0 synth pi fade 0 .25 .15 pad 0 1 reverb overdrive riaa norm -8 speed 1 &')
|
||||
@ -38,6 +45,7 @@ def on_fullscreen(self,i3):
|
||||
i3 = i3ipc.Connection()
|
||||
|
||||
i3.on('window::new', on_new_window)
|
||||
i3.on('window::close', on_close_window)
|
||||
i3.on(Event.MODE, on_mode)
|
||||
i3.on('workspace::focus', on_workspace_focus)
|
||||
i3.on('window::move', on_workspace_move)
|
||||
|
@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
path="$(readlink -f $0)"
|
||||
path="${path%/*/*}"
|
||||
path="${path##*/}"
|
||||
if [[ "$path" == "i3" ]]; then
|
||||
mapfile -t windowList < <(python3 -c '
|
||||
import i3ipc
|
||||
|
||||
@ -13,4 +17,28 @@ id="$(yad --title "I38" --list --separator "" --column "id" --column "Select Win
|
||||
if [[ -z "${id}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
i3-msg \[id="${id}"\] focus
|
||||
i3-msg \[id="${id}"\] focus
|
||||
else
|
||||
mapfile -t windowList < <(python3 -c '
|
||||
import i3ipc
|
||||
|
||||
i3 = i3ipc.Connection()
|
||||
|
||||
for con in i3.get_tree():
|
||||
if con.window or con.type == "con":
|
||||
if con.name:
|
||||
print(con.window)
|
||||
print(con.name)')
|
||||
|
||||
# Remove the first entry if it is "none"
|
||||
if [[ "${windowList[0]}" == "none" ]]; then
|
||||
unset "windowList[0]"
|
||||
fi
|
||||
|
||||
id="$(yad --title "I38" --list --separator "" --column "id" --column "Select Window" --hide-column 1 --print-column 1 "${windowList[@]}")"
|
||||
|
||||
if [[ -z "${id}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
swaymsg \[id="${id}"\] focus
|
||||
fi
|
||||
|
Reference in New Issue
Block a user