init
This commit is contained in:
commit
9ec09f9238
96
config
Normal file
96
config
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# i3blocks configuration file
|
||||||
|
#
|
||||||
|
# The i3blocks man page describes the usage of the binary,
|
||||||
|
# and its website describes the configuration:
|
||||||
|
#
|
||||||
|
# https://vivien.github.io/i3blocks
|
||||||
|
|
||||||
|
SCRIPT_DIR=/home/arco/.config/i3blocks/scripts
|
||||||
|
|
||||||
|
# Global properties
|
||||||
|
separator=true
|
||||||
|
separator_block_width=30
|
||||||
|
|
||||||
|
[mediaplayer]
|
||||||
|
command=$SCRIPT_DIR/mediaplayer
|
||||||
|
interval=1
|
||||||
|
|
||||||
|
#[documentation]
|
||||||
|
#full_text=Documentation
|
||||||
|
#website=https://vivien.github.io/i3blocks
|
||||||
|
#command=xdg-open "$website"
|
||||||
|
#color=#f12711
|
||||||
|
|
||||||
|
#[greetings]
|
||||||
|
#color=#f5af19
|
||||||
|
#command=echo "Hello, $USER!"
|
||||||
|
#interval=once
|
||||||
|
|
||||||
|
[volume]
|
||||||
|
command=$SCRIPT_DIR/volume
|
||||||
|
LABEL=♪
|
||||||
|
#LABEL=VOL
|
||||||
|
interval=once
|
||||||
|
signal=10
|
||||||
|
STEP=5%
|
||||||
|
MIXER=pulse
|
||||||
|
#SCONTROL=[determined automatically]
|
||||||
|
#NATURAL_MAPPING=0
|
||||||
|
|
||||||
|
[dunst]
|
||||||
|
command=$SCRIPT_DIR/dunst
|
||||||
|
interval=once
|
||||||
|
format=json
|
||||||
|
markup=pango
|
||||||
|
#min_width=50
|
||||||
|
align=center
|
||||||
|
|
||||||
|
[disk]
|
||||||
|
command=$SCRIPT_DIR/disk
|
||||||
|
DIR=/
|
||||||
|
LABEL=🖴
|
||||||
|
interval=30
|
||||||
|
|
||||||
|
[batterybar]
|
||||||
|
command=$SCRIPT_DIR/batterybar
|
||||||
|
label=⏻
|
||||||
|
interval=5
|
||||||
|
markup=pango
|
||||||
|
min_width=bat: ■■■■■
|
||||||
|
# Discharging colors low to high
|
||||||
|
C1=#FF0027
|
||||||
|
C2=#FF3B05
|
||||||
|
C3=#FFB923
|
||||||
|
C4=#FFD000
|
||||||
|
C5=#E4FF00
|
||||||
|
C6=#ADFF00
|
||||||
|
C7=#6DFF00
|
||||||
|
C8=#10BA00
|
||||||
|
CHARGING_COLOR=#00AFE3
|
||||||
|
FULL_COLOR=#FFFFFF
|
||||||
|
AC_COLOR=#535353
|
||||||
|
|
||||||
|
[time]
|
||||||
|
command=date '+%m/%d/%Y %H:%M'
|
||||||
|
interval=15
|
||||||
|
|
||||||
|
[shutdown_menu]
|
||||||
|
full_text= ⏻ Power Menu
|
||||||
|
# If you are using FontAwesome, we recommend the power-off icon:
|
||||||
|
# http://fontawesome.io/icon/power-off/
|
||||||
|
command=$SCRIPT_DIR/shutdown_menu
|
||||||
|
#FG_COLOR=#bbbbbb
|
||||||
|
#BG_COLOR=#111111
|
||||||
|
#HLFG_COLOR=#111111
|
||||||
|
#HLBG_COLOR=#bbbbbb
|
||||||
|
#BORDER_COLOR=#222222
|
||||||
|
ROFI_TEXT=⏻
|
||||||
|
ROFI_OPTIONS=-width 11 -location 0 -hide-scrollbar -bw 2
|
||||||
|
#ZENITY_TITLE=Menu
|
||||||
|
#ZENITY_TEXT=Action:
|
||||||
|
#ZENITY_OPTIONS=--column= --hide-header
|
||||||
|
#ENABLE_CONFIRMATIONS=true (must be true or false)
|
||||||
|
#LAUNCHER=rofi #(must be rofi or zenity)
|
||||||
|
LOCKSCRIPT=betterlockscreen -u "/home/arco/Wallpapers/platform.jpg" -l
|
||||||
|
background=#d79921
|
||||||
|
color=#282828
|
155
scripts/arch-update
Executable file
155
scripts/arch-update
Executable file
@ -0,0 +1,155 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017 Marcel Patzwahl
|
||||||
|
# Licensed under the terms of the GNU GPL v3 only.
|
||||||
|
#
|
||||||
|
# i3blocks blocklet script to see the available updates of pacman and the AUR
|
||||||
|
import subprocess
|
||||||
|
from subprocess import check_output
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def create_argparse():
|
||||||
|
def _default(name, default='', arg_type=str):
|
||||||
|
val = default
|
||||||
|
if name in os.environ:
|
||||||
|
val = os.environ[name]
|
||||||
|
return arg_type(val)
|
||||||
|
|
||||||
|
strbool = lambda s: s.lower() in ['t', 'true', '1']
|
||||||
|
strlist = lambda s: s.split()
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Check for pacman updates')
|
||||||
|
parser.add_argument(
|
||||||
|
'-b',
|
||||||
|
'--base_color',
|
||||||
|
default = _default('BASE_COLOR', 'green'),
|
||||||
|
help='base color of the output(default=green)'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-u',
|
||||||
|
'--updates_available_color',
|
||||||
|
default = _default('UPDATE_COLOR', 'yellow'),
|
||||||
|
help='color of the output, when updates are available(default=yellow)'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-a',
|
||||||
|
'--aur',
|
||||||
|
action = 'store_const',
|
||||||
|
const = True,
|
||||||
|
default = _default('AUR', 'False', strbool),
|
||||||
|
help='Include AUR packages. Attn: Yaourt must be installed'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-y',
|
||||||
|
'--aur_yay',
|
||||||
|
action = 'store_const',
|
||||||
|
const = True,
|
||||||
|
default = _default('AUR_YAY', 'False', strbool),
|
||||||
|
help='Include AUR packages. Attn: Yay must be installed'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-q',
|
||||||
|
'--quiet',
|
||||||
|
action = 'store_const',
|
||||||
|
const = True,
|
||||||
|
default = _default('QUIET', 'False', strbool),
|
||||||
|
help = 'Do not produce output when system is up to date'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'-w',
|
||||||
|
'--watch',
|
||||||
|
nargs='*',
|
||||||
|
default = _default('WATCH', arg_type=strlist),
|
||||||
|
help='Explicitly watch for specified packages. '
|
||||||
|
'Listed elements are treated as regular expressions for matching.'
|
||||||
|
)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def get_updates():
|
||||||
|
output = ''
|
||||||
|
try:
|
||||||
|
output = check_output(['checkupdates']).decode('utf-8')
|
||||||
|
except subprocess.CalledProcessError as exc:
|
||||||
|
# checkupdates exits with 2 and no output if no updates are available.
|
||||||
|
# we ignore this case and go on
|
||||||
|
if not (exc.returncode == 2 and not exc.output):
|
||||||
|
raise exc
|
||||||
|
if not output:
|
||||||
|
return []
|
||||||
|
|
||||||
|
updates = [line.split(' ')[0]
|
||||||
|
for line in output.split('\n')
|
||||||
|
if line]
|
||||||
|
|
||||||
|
return updates
|
||||||
|
|
||||||
|
|
||||||
|
def get_aur_yaourt_updates():
|
||||||
|
output = ''
|
||||||
|
try:
|
||||||
|
output = check_output(['yaourt', '-Qua']).decode('utf-8')
|
||||||
|
except subprocess.CalledProcessError as exc:
|
||||||
|
# yaourt exits with 1 and no output if no updates are available.
|
||||||
|
# we ignore this case and go on
|
||||||
|
if not (exc.returncode == 1 and not exc.output):
|
||||||
|
raise exc
|
||||||
|
if not output:
|
||||||
|
return []
|
||||||
|
|
||||||
|
aur_updates = [line.split(' ')[0]
|
||||||
|
for line in output.split('\n')
|
||||||
|
if line.startswith('aur/')]
|
||||||
|
|
||||||
|
return aur_updates
|
||||||
|
|
||||||
|
def get_aur_yay_updates():
|
||||||
|
output = check_output(['yay', '-Qua']).decode('utf-8')
|
||||||
|
if not output:
|
||||||
|
return []
|
||||||
|
|
||||||
|
aur_updates = [line.split(' ')[0] for line in output.split('\n') if line]
|
||||||
|
|
||||||
|
return aur_updates
|
||||||
|
|
||||||
|
|
||||||
|
def matching_updates(updates, watch_list):
|
||||||
|
matches = set()
|
||||||
|
for u in updates:
|
||||||
|
for w in watch_list:
|
||||||
|
if re.match(w, u):
|
||||||
|
matches.add(u)
|
||||||
|
|
||||||
|
return matches
|
||||||
|
|
||||||
|
|
||||||
|
label = os.environ.get("LABEL","")
|
||||||
|
message = "{0}<span color='{1}'>{2}</span>"
|
||||||
|
args = create_argparse()
|
||||||
|
|
||||||
|
updates = get_updates()
|
||||||
|
if args.aur:
|
||||||
|
updates += get_aur_yaourt_updates()
|
||||||
|
elif args.aur_yay:
|
||||||
|
updates += get_aur_yay_updates()
|
||||||
|
|
||||||
|
update_count = len(updates)
|
||||||
|
if update_count > 0:
|
||||||
|
if update_count == 1:
|
||||||
|
info = str(update_count) + ' update available'
|
||||||
|
short_info = str(update_count) + ' update'
|
||||||
|
else:
|
||||||
|
info = str(update_count) + ' updates available'
|
||||||
|
short_info = str(update_count) + ' updates'
|
||||||
|
|
||||||
|
matches = matching_updates(updates, args.watch)
|
||||||
|
if matches:
|
||||||
|
info += ' [{0}]'.format(', '.join(matches))
|
||||||
|
short_info += '*'
|
||||||
|
print(message.format(label, args.updates_available_color, info))
|
||||||
|
print(message.format(label, args.updates_available_color, short_info))
|
||||||
|
elif not args.quiet:
|
||||||
|
print(message.format(label, args.base_color, 'system up to date'))
|
137
scripts/batterybar
Executable file
137
scripts/batterybar
Executable file
@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# batterybar; displays battery percentage as a bar on i3blocks
|
||||||
|
#
|
||||||
|
# Copyright 2015 Keftaa <adnan.37h@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
# MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
readarray -t output <<< $(acpi battery)
|
||||||
|
battery_count=${#output[@]}
|
||||||
|
|
||||||
|
for line in "${output[@]}";
|
||||||
|
do
|
||||||
|
percentages+=($(echo "$line" | grep -o -m1 '[0-9]\{1,3\}%' | tr -d '%'))
|
||||||
|
statuses+=($(echo "$line" | egrep -o -m1 'Discharging|Charging|AC|Full|Unknown'))
|
||||||
|
remaining=$(echo "$line" | egrep -o -m1 '[0-9][0-9]:[0-9][0-9]')
|
||||||
|
if [[ -n $remaining ]]; then
|
||||||
|
remainings+=(" ($remaining)")
|
||||||
|
else
|
||||||
|
remainings+=("")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
squares="■"
|
||||||
|
|
||||||
|
#There are 8 colors that reflect the current battery percentage when
|
||||||
|
#discharging
|
||||||
|
dis_colors=("${C1:-#FF0027}" "${C2:-#FF3B05}" "${C3:-#FFB923}"
|
||||||
|
"${C4:-#FFD000}" "${C5:-#E4FF00}" "${C6:-#ADFF00}"
|
||||||
|
"${C7:-#6DFF00}" "${C8:-#10BA00}")
|
||||||
|
charging_color="${CHARGING_COLOR:-#00AFE3}"
|
||||||
|
full_color="${FULL_COLOR:-#FFFFFF}"
|
||||||
|
ac_color="${AC_COLOR:-#535353}"
|
||||||
|
|
||||||
|
|
||||||
|
while getopts 1:2:3:4:5:6:7:8:c:f:a:h opt; do
|
||||||
|
case "$opt" in
|
||||||
|
1) dis_colors[0]="$OPTARG";;
|
||||||
|
2) dis_colors[1]="$OPTARG";;
|
||||||
|
3) dis_colors[2]="$OPTARG";;
|
||||||
|
4) dis_colors[3]="$OPTARG";;
|
||||||
|
5) dis_colors[4]="$OPTARG";;
|
||||||
|
6) dis_colors[5]="$OPTARG";;
|
||||||
|
7) dis_colors[6]="$OPTARG";;
|
||||||
|
8) dis_colors[7]="$OPTARG";;
|
||||||
|
c) charging_color="$OPTARG";;
|
||||||
|
f) full_color="$OPTARG";;
|
||||||
|
a) ac_color="$OPTARG";;
|
||||||
|
h) printf "Usage: batterybar [OPTION] color
|
||||||
|
When discharging, there are 8 [1-8] levels colors.
|
||||||
|
You can specify custom colors, for example:
|
||||||
|
|
||||||
|
batterybar -1 red -2 \"#F6F6F6\" -8 green
|
||||||
|
|
||||||
|
You can also specify the colors for the charging, AC and
|
||||||
|
charged states:
|
||||||
|
|
||||||
|
batterybar -c green -f white -a \"#EEEEEE\"\n";
|
||||||
|
exit 0;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
end=$(($battery_count - 1))
|
||||||
|
for i in $(seq 0 $end);
|
||||||
|
do
|
||||||
|
if (( percentages[$i] > 0 && percentages[$i] < 20 )); then
|
||||||
|
squares="■"
|
||||||
|
elif (( percentages[$i] >= 20 && percentages[$i] < 40 )); then
|
||||||
|
squares="■■"
|
||||||
|
elif (( percentages[$i] >= 40 && percentages[$i] < 60 )); then
|
||||||
|
squares="■■■"
|
||||||
|
elif (( percentages[$i] >= 60 && percentages[$i] < 80 )); then
|
||||||
|
squares="■■■■"
|
||||||
|
elif (( percentages[$i] >=80 )); then
|
||||||
|
squares="■■■■■"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${statuses[$i]}" = "Unknown" ]]; then
|
||||||
|
squares="<sup>?</sup>$squares"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${statuses[$i]}" in
|
||||||
|
"Charging")
|
||||||
|
color="$charging_color"
|
||||||
|
;;
|
||||||
|
"Full")
|
||||||
|
color="$full_color"
|
||||||
|
;;
|
||||||
|
"AC")
|
||||||
|
color="$ac_color"
|
||||||
|
;;
|
||||||
|
"Discharging"|"Unknown")
|
||||||
|
if (( percentages[$i] >= 0 && percentages[$i] < 10 )); then
|
||||||
|
color="${dis_colors[0]}"
|
||||||
|
elif (( percentages[$i] >= 10 && percentages[$i] < 20 )); then
|
||||||
|
color="${dis_colors[1]}"
|
||||||
|
elif (( percentages[$i] >= 20 && percentages[$i] < 30 )); then
|
||||||
|
color="${dis_colors[2]}"
|
||||||
|
elif (( percentages[$i] >= 30 && percentages[$i] < 40 )); then
|
||||||
|
color="${dis_colors[3]}"
|
||||||
|
elif (( percentages[$i] >= 40 && percentages[$i] < 60 )); then
|
||||||
|
color="${dis_colors[4]}"
|
||||||
|
elif (( percentages[$i] >= 60 && percentages[$i] < 70 )); then
|
||||||
|
color="${dis_colors[5]}"
|
||||||
|
elif (( percentages[$i] >= 70 && percentages[$i] < 80 )); then
|
||||||
|
color="${dis_colors[6]}"
|
||||||
|
elif (( percentages[$i] >= 80 )); then
|
||||||
|
color="${dis_colors[7]}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Print Battery number if there is more than one
|
||||||
|
if (( $end > 0 )) ; then
|
||||||
|
message="$message $(($i + 1)):"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$BLOCK_BUTTON" -eq 1 ]]; then
|
||||||
|
message="$message ${statuses[$i]} <span foreground=\"$color\">${percentages[$i]}%${remainings[i]}</span>"
|
||||||
|
fi
|
||||||
|
message="$message <span foreground=\"$color\">$squares</span>"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $message
|
48
scripts/disk
Executable file
48
scripts/disk
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
DIR="${DIR:-$BLOCK_INSTANCE}"
|
||||||
|
DIR="${DIR:-$HOME}"
|
||||||
|
ALERT_LOW="${ALERT_LOW:-$1}"
|
||||||
|
ALERT_LOW="${ALERT_LOW:-10}" # color will turn red under this value (default: 10%)
|
||||||
|
|
||||||
|
LOCAL_FLAG="-l"
|
||||||
|
if [ "$1" = "-n" ] || [ "$2" = "-n" ]; then
|
||||||
|
LOCAL_FLAG=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
df -h -P $LOCAL_FLAG "$DIR" | awk -v label="$LABEL" -v alert_low=$ALERT_LOW '
|
||||||
|
/\/.*/ {
|
||||||
|
# full text
|
||||||
|
print label $4
|
||||||
|
|
||||||
|
# short text
|
||||||
|
print label $4
|
||||||
|
|
||||||
|
use=$5
|
||||||
|
|
||||||
|
# no need to continue parsing
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
gsub(/%$/,"",use)
|
||||||
|
if (100 - use < alert_low) {
|
||||||
|
# color
|
||||||
|
print "#FF0000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'
|
40
scripts/dunst
Executable file
40
scripts/dunst
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
A do-not-disturb button for muting Dunst notifications in i3 using i3blocks
|
||||||
|
|
||||||
|
Mute is handled using the `dunstctl` command.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Jessey White-Cinis <j@cin.is>"
|
||||||
|
__copyright__ = "Copyright (c) 2019 Jessey White-Cinis"
|
||||||
|
__license__ = "MIT"
|
||||||
|
__version__ = "1.1.0"
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess as sp
|
||||||
|
import json
|
||||||
|
|
||||||
|
def mute_toggle():
|
||||||
|
'''Toggle dunst notifications'''
|
||||||
|
sp.run(["dunstctl", "set-paused", "toggle"], check=True)
|
||||||
|
|
||||||
|
def clicked():
|
||||||
|
'''Returns True if the button was clicked'''
|
||||||
|
button = os.environ.get("BLOCK_BUTTON", None)
|
||||||
|
return bool(button)
|
||||||
|
|
||||||
|
def muted():
|
||||||
|
'''Returns True if Dunst is muted'''
|
||||||
|
output = sp.check_output(('dunstctl', 'is-paused'))
|
||||||
|
return u'true' == output.strip().decode("UTF-8")
|
||||||
|
|
||||||
|
if clicked():
|
||||||
|
# toggle button click to turn mute on and off
|
||||||
|
mute_toggle()
|
||||||
|
|
||||||
|
if muted():
|
||||||
|
RTN = {"full_text":"<span font='Font Awesome 5 Free Solid' color='#BE616E'>\uf1f6</span>"}
|
||||||
|
else:
|
||||||
|
RTN = {"full_text":"<span font='Font Awesome 5 Free Solid' color='#A4B98E'>\uf0f3</span>"}
|
||||||
|
|
||||||
|
print(json.dumps(RTN))
|
159
scripts/mediaplayer
Executable file
159
scripts/mediaplayer
Executable file
@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
# Copyright (C) 2014 Tony Crisci <tony@dubstepdish.com>
|
||||||
|
# Copyright (C) 2015 Thiago Perrotta <perrotta dot thiago at poli dot ufrj dot br>
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# For all media players except mpd/cmus/rhythmbox, MPRIS support should be
|
||||||
|
# enabled and the playerctl binary should be in your path.
|
||||||
|
# See https://github.com/acrisci/playerctl
|
||||||
|
|
||||||
|
# Set instance=NAME in the i3blocks configuration to specify a music player
|
||||||
|
# (playerctl will attempt to connect to org.mpris.MediaPlayer2.[NAME] on your
|
||||||
|
# DBus session). If instance is empty, playerctl will connect to the first
|
||||||
|
# supported media player it finds.
|
||||||
|
|
||||||
|
use Time::HiRes qw(usleep);
|
||||||
|
use Env qw(BLOCK_INSTANCE);
|
||||||
|
|
||||||
|
use constant DELAY => 50; # Delay in ms to let network-based players (spotify) reflect new data.
|
||||||
|
use constant SPOTIFY_STR => 'spotify';
|
||||||
|
|
||||||
|
my @metadata = ();
|
||||||
|
my $player_arg = "";
|
||||||
|
|
||||||
|
if ($BLOCK_INSTANCE) {
|
||||||
|
$player_arg = "--player='$BLOCK_INSTANCE'";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub buttons {
|
||||||
|
my $method = shift;
|
||||||
|
|
||||||
|
if($method eq 'mpd') {
|
||||||
|
if ($ENV{'BLOCK_BUTTON'} == 1) {
|
||||||
|
system("mpc prev &>/dev/null");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 2) {
|
||||||
|
system("mpc toggle &>/dev/null");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 3) {
|
||||||
|
system("mpc next &>/dev/null");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 4) {
|
||||||
|
system("mpc volume +10 &>/dev/null");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 5) {
|
||||||
|
system("mpc volume -10 &>/dev/null");
|
||||||
|
}
|
||||||
|
} elsif ($method eq 'cmus') {
|
||||||
|
if ($ENV{'BLOCK_BUTTON'} == 1) {
|
||||||
|
system("cmus-remote --prev");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 2) {
|
||||||
|
system("cmus-remote --pause");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 3) {
|
||||||
|
system("cmus-remote --next");
|
||||||
|
}
|
||||||
|
} elsif ($method eq 'playerctl') {
|
||||||
|
if ($ENV{'BLOCK_BUTTON'} == 1) {
|
||||||
|
system("playerctl $player_arg previous");
|
||||||
|
usleep(DELAY * 1000) if $BLOCK_INSTANCE eq SPOTIFY_STR;
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 2) {
|
||||||
|
system("playerctl $player_arg play-pause");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 3) {
|
||||||
|
system("playerctl $player_arg next");
|
||||||
|
usleep(DELAY * 1000) if $BLOCK_INSTANCE eq SPOTIFY_STR;
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 4) {
|
||||||
|
system("playerctl $player_arg volume 0.01+");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 5) {
|
||||||
|
system("playerctl $player_arg volume 0.01-");
|
||||||
|
}
|
||||||
|
} elsif ($method eq 'rhythmbox') {
|
||||||
|
if ($ENV{'BLOCK_BUTTON'} == 1) {
|
||||||
|
system("rhythmbox-client --previous");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 2) {
|
||||||
|
system("rhythmbox-client --play-pause");
|
||||||
|
} elsif ($ENV{'BLOCK_BUTTON'} == 3) {
|
||||||
|
system("rhythmbox-client --next");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cmus {
|
||||||
|
my @cmus = split /^/, qx(cmus-remote -Q);
|
||||||
|
if ($? == 0) {
|
||||||
|
foreach my $line (@cmus) {
|
||||||
|
my @data = split /\s/, $line;
|
||||||
|
if (shift @data eq 'tag') {
|
||||||
|
my $key = shift @data;
|
||||||
|
my $value = join ' ', @data;
|
||||||
|
|
||||||
|
@metadata[0] = $value if $key eq 'artist';
|
||||||
|
@metadata[1] = $value if $key eq 'title';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@metadata) {
|
||||||
|
buttons('cmus');
|
||||||
|
|
||||||
|
# metadata found so we are done
|
||||||
|
print(join ' - ', @metadata);
|
||||||
|
print("\n");
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub mpd {
|
||||||
|
my $data = qx(mpc current);
|
||||||
|
if (not $data eq '') {
|
||||||
|
buttons("mpd");
|
||||||
|
print($data);
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub playerctl {
|
||||||
|
buttons('playerctl');
|
||||||
|
|
||||||
|
my $artist = qx(playerctl $player_arg metadata artist 2>/dev/null);
|
||||||
|
chomp $artist;
|
||||||
|
# exit status will be nonzero when playerctl cannot find your player
|
||||||
|
exit(0) if $? || $artist eq '(null)';
|
||||||
|
|
||||||
|
push(@metadata, $artist) if $artist;
|
||||||
|
|
||||||
|
my $title = qx(playerctl $player_arg metadata title);
|
||||||
|
exit(0) if $? || $title eq '(null)';
|
||||||
|
|
||||||
|
push(@metadata, $title) if $title;
|
||||||
|
|
||||||
|
print(join(" - ", @metadata)) if @metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rhythmbox {
|
||||||
|
buttons('rhythmbox');
|
||||||
|
|
||||||
|
my $data = qx(rhythmbox-client --print-playing --no-start);
|
||||||
|
print($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($player_arg =~ /mpd/) {
|
||||||
|
mpd;
|
||||||
|
}
|
||||||
|
elsif ($player_arg =~ /cmus/) {
|
||||||
|
cmus;
|
||||||
|
}
|
||||||
|
elsif ($player_arg =~ /rhythmbox/) {
|
||||||
|
rhythmbox;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playerctl;
|
||||||
|
}
|
||||||
|
print("\n");
|
43
scripts/playerctl
Executable file
43
scripts/playerctl
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Based on https://aur.archlinux.org/packages/playerctl/
|
||||||
|
|
||||||
|
INSTANCE="${BLOCK_INSTANCE}"
|
||||||
|
|
||||||
|
if [[ "${INSTANCE}" != "" ]]; then
|
||||||
|
ARGUMENTS="--player ${INSTANCE}"
|
||||||
|
ps -e | grep "${INSTANCE}" &> /dev/null
|
||||||
|
fi
|
||||||
|
if [ $? == 1 ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ICON_PLAY="➤"
|
||||||
|
ICON_PAUSE="Ⅱ"
|
||||||
|
ICON_STOP="≠"
|
||||||
|
CUR_ICON=""
|
||||||
|
|
||||||
|
if [[ "${BLOCK_BUTTON}" -eq 1 ]]; then
|
||||||
|
$(playerctl ${ARGUMENTS} previous)
|
||||||
|
elif [[ "${BLOCK_BUTTON}" -eq 2 ]]; then
|
||||||
|
$(playerctl ${ARGUMENTS} play-pause)
|
||||||
|
elif [[ "${BLOCK_BUTTON}" -eq 3 ]]; then
|
||||||
|
$(playerctl ${ARGUMENTS} next)
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLAYER_STATUS=$(playerctl ${ARGUMENTS} status)
|
||||||
|
INFO_TITLE=$(playerctl ${ARGUMENTS} metadata title)
|
||||||
|
INFO_ALBUM=$(playerctl ${ARGUMENTS} metadata album)
|
||||||
|
INFO_ARTIST=$(playerctl ${ARGUMENTS} metadata artist)
|
||||||
|
|
||||||
|
if [[ "${PLAYER_STATUS}" = "Paused" ]]; then
|
||||||
|
CUR_ICON="${ICON_PAUSE}"
|
||||||
|
elif [[ "${PLAYER_STATUS}" = "Playing" ]]; then
|
||||||
|
CUR_ICON="${ICON_PLAY}"
|
||||||
|
else
|
||||||
|
CUR_ICON="${ICON_STOP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${INFO_TITLE}" != "" ]] && [[ "${INFO_ARTIST}" != "" ]]; then
|
||||||
|
echo "${INFO_ARTIST} - ${INFO_TITLE} ${CUR_ICON}"
|
||||||
|
echo "${INFO_ARTIST} - ${INFO_TITLE} ${CUR_ICON}"
|
||||||
|
fi
|
186
scripts/shutdown_menu
Executable file
186
scripts/shutdown_menu
Executable file
@ -0,0 +1,186 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Use rofi/zenity to change system runstate thanks to systemd.
|
||||||
|
#
|
||||||
|
# Note: this currently relies on associative array support in the shell.
|
||||||
|
#
|
||||||
|
# Inspired from i3pystatus wiki:
|
||||||
|
# https://github.com/enkore/i3pystatus/wiki/Shutdown-Menu
|
||||||
|
#
|
||||||
|
# Copyright 2015 Benjamin Chrétien <chretien at lirmm dot fr>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# BEGIN CONFIG #
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
# Use a custom lock script
|
||||||
|
#LOCKSCRIPT="i3lock-extra -m pixelize"
|
||||||
|
|
||||||
|
# Colors: FG (foreground), BG (background), HL (highlighted)
|
||||||
|
FG_COLOR="${FG_COLOR:-#bbbbbb}"
|
||||||
|
BG_COLOR="${BG_COLOR:-#111111}"
|
||||||
|
HLFG_COLOR="${HLFG_COLOR:-#111111}"
|
||||||
|
HLBG_COLOR="${HLBG_COLOR:-#bbbbbb}"
|
||||||
|
BORDER_COLOR="${BORDER_COLOR:-#222222}"
|
||||||
|
|
||||||
|
# Options not related to colors
|
||||||
|
ROFI_TEXT="${ROFI_TEXT:-Menu:}"
|
||||||
|
ROFI_OPTIONS=(${ROFI_OPTIONS:--theme-str 'window {width: 11%; border: 2;} listview {scrollbar: false;}' -location 3})
|
||||||
|
|
||||||
|
# Zenity options
|
||||||
|
ZENITY_TITLE="${ZENITY_TITLE:-Menu}"
|
||||||
|
ZENITY_TEXT="${ZENITY_TEXT:-Action:}"
|
||||||
|
ZENITY_OPTIONS=(${ZENITY_OPTIONS:---column= --hide-header})
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# END CONFIG #
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
# Whether to ask for user's confirmation
|
||||||
|
enable_confirmation=${ENABLE_CONFIRMATIONS:-false}
|
||||||
|
|
||||||
|
# Preferred launcher if both are available
|
||||||
|
preferred_launcher="${LAUNCHER:-rofi}"
|
||||||
|
|
||||||
|
usage="$(basename "$0") [-h] [-c] [-p name] -- display a menu for shutdown, reboot, lock etc.
|
||||||
|
|
||||||
|
where:
|
||||||
|
-h show this help text
|
||||||
|
-c ask for user confirmation
|
||||||
|
-p preferred launcher (rofi or zenity)
|
||||||
|
|
||||||
|
This script depends on:
|
||||||
|
- systemd,
|
||||||
|
- i3,
|
||||||
|
- rofi or zenity."
|
||||||
|
|
||||||
|
# Check whether the user-defined launcher is valid
|
||||||
|
launcher_list=(rofi zenity)
|
||||||
|
function check_launcher() {
|
||||||
|
if [[ ! "${launcher_list[@]}" =~ (^|[[:space:]])"$1"($|[[:space:]]) ]]; then
|
||||||
|
echo "Supported launchers: ${launcher_list[*]}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# Get array with unique elements and preferred launcher first
|
||||||
|
# Note: uniq expects a sorted list, so we cannot use it
|
||||||
|
i=1
|
||||||
|
launcher_list=($(for l in "$1" "${launcher_list[@]}"; do printf "%i %s\n" "$i" "$l"; let i+=1; done \
|
||||||
|
| sort -uk2 | sort -nk1 | cut -d' ' -f2- | tr '\n' ' '))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse CLI arguments
|
||||||
|
while getopts "hcp:" option; do
|
||||||
|
case "${option}" in
|
||||||
|
h) echo "${usage}"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
c) enable_confirmation=true
|
||||||
|
;;
|
||||||
|
p) preferred_launcher="${OPTARG}"
|
||||||
|
check_launcher "${preferred_launcher}"
|
||||||
|
;;
|
||||||
|
*) exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
check_launcher "${preferred_launcher}"
|
||||||
|
|
||||||
|
# Check whether a command exists
|
||||||
|
function command_exists() {
|
||||||
|
command -v "$1" &> /dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# systemctl required
|
||||||
|
if ! command_exists systemctl ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# menu defined as an associative array
|
||||||
|
typeset -A menu
|
||||||
|
|
||||||
|
# Menu with keys/commands
|
||||||
|
menu=(
|
||||||
|
[Shutdown]="systemctl poweroff"
|
||||||
|
[Reboot]="systemctl reboot"
|
||||||
|
[Hibernate]="systemctl hibernate"
|
||||||
|
[Suspend]="systemctl suspend"
|
||||||
|
[Halt]="systemctl halt"
|
||||||
|
[Lock]="${LOCKSCRIPT:-i3lock --color=${BG_COLOR#"#"}}"
|
||||||
|
[Logout]="i3-msg exit"
|
||||||
|
[Cancel]=""
|
||||||
|
)
|
||||||
|
menu_nrows=${#menu[@]}
|
||||||
|
|
||||||
|
# Menu entries that may trigger a confirmation message
|
||||||
|
menu_confirm="Shutdown Reboot Hibernate Suspend Halt Logout"
|
||||||
|
|
||||||
|
launcher_exe=""
|
||||||
|
launcher_options=""
|
||||||
|
rofi_colors=""
|
||||||
|
|
||||||
|
function prepare_launcher() {
|
||||||
|
if [[ "$1" == "rofi" ]]; then
|
||||||
|
rofi_colors=(-bc "${BORDER_COLOR}" -bg "${BG_COLOR}" -fg "${FG_COLOR}" \
|
||||||
|
-hlfg "${HLFG_COLOR}" -hlbg "${HLBG_COLOR}")
|
||||||
|
launcher_exe="rofi"
|
||||||
|
launcher_options=(-dmenu -i -lines "${menu_nrows}" -p "${ROFI_TEXT}" \
|
||||||
|
"${rofi_colors[@]}" "${ROFI_OPTIONS[@]}")
|
||||||
|
elif [[ "$1" == "zenity" ]]; then
|
||||||
|
launcher_exe="zenity"
|
||||||
|
launcher_options=(--list --title="${ZENITY_TITLE}" --text="${ZENITY_TEXT}" \
|
||||||
|
"${ZENITY_OPTIONS[@]}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
for l in "${launcher_list[@]}"; do
|
||||||
|
if command_exists "${l}" ; then
|
||||||
|
prepare_launcher "${l}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# No launcher available
|
||||||
|
if [[ -z "${launcher_exe}" ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
launcher=(${launcher_exe} "${launcher_options[@]}")
|
||||||
|
selection="$(printf '%s\n' "${!menu[@]}" | sort | "${launcher[@]}")"
|
||||||
|
|
||||||
|
function ask_confirmation() {
|
||||||
|
if [ "${launcher_exe}" == "rofi" ]; then
|
||||||
|
confirmed=$(echo -e "Yes\nNo" | rofi -dmenu -i -lines 2 -p "${selection}?" \
|
||||||
|
"${rofi_colors[@]}" "${ROFI_OPTIONS[@]}")
|
||||||
|
[ "${confirmed}" == "Yes" ] && confirmed=0
|
||||||
|
elif [ "${launcher_exe}" == "zenity" ]; then
|
||||||
|
zenity --question --text "Are you sure you want to ${selection,,}?"
|
||||||
|
confirmed=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${confirmed}" == 0 ]; then
|
||||||
|
i3-msg -q "exec ${menu[${selection}]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $? -eq 0 && ! -z ${selection} ]]; then
|
||||||
|
if [[ "${enable_confirmation}" = true && \
|
||||||
|
${menu_confirm} =~ (^|[[:space:]])"${selection}"($|[[:space:]]) ]]; then
|
||||||
|
ask_confirmation
|
||||||
|
else
|
||||||
|
i3-msg -q "exec ${menu[${selection}]}"
|
||||||
|
fi
|
||||||
|
fi
|
91
scripts/volume
Executable file
91
scripts/volume
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (C) 2014 Julien Bonjean <julien@bonjean.info>
|
||||||
|
# Copyright (C) 2014 Alexander Keller <github@nycroth.com>
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The second parameter overrides the mixer selection
|
||||||
|
# For PulseAudio users, eventually use "pulse"
|
||||||
|
# For Jack/Jack2 users, use "jackplug"
|
||||||
|
# For ALSA users, you may use "default" for your primary card
|
||||||
|
# or you may use hw:# where # is the number of the card desired
|
||||||
|
if [[ -z "$MIXER" ]] ; then
|
||||||
|
MIXER="default"
|
||||||
|
if command -v pulseaudio >/dev/null 2>&1 && pulseaudio --check ; then
|
||||||
|
# pulseaudio is running, but not all installations use "pulse"
|
||||||
|
if amixer -D pulse info >/dev/null 2>&1 ; then
|
||||||
|
MIXER="pulse"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
[ -n "$(lsmod | grep jack)" ] && MIXER="jackplug"
|
||||||
|
MIXER="${2:-$MIXER}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The instance option sets the control to report and configure
|
||||||
|
# This defaults to the first control of your selected mixer
|
||||||
|
# For a list of the available, use `amixer -D $Your_Mixer scontrols`
|
||||||
|
if [[ -z "$SCONTROL" ]] ; then
|
||||||
|
SCONTROL="${BLOCK_INSTANCE:-$(amixer -D $MIXER scontrols |
|
||||||
|
sed -n "s/Simple mixer control '\([^']*\)',0/\1/p" |
|
||||||
|
head -n1
|
||||||
|
)}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The first parameter sets the step to change the volume by (and units to display)
|
||||||
|
# This may be in in % or dB (eg. 5% or 3dB)
|
||||||
|
if [[ -z "$STEP" ]] ; then
|
||||||
|
STEP="${1:-5%}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# AMIXER(1):
|
||||||
|
# "Use the mapped volume for evaluating the percentage representation like alsamixer, to be
|
||||||
|
# more natural for human ear."
|
||||||
|
NATURAL_MAPPING=${NATURAL_MAPPING:-0}
|
||||||
|
if [[ "$NATURAL_MAPPING" != "0" ]] ; then
|
||||||
|
AMIXER_PARAMS="-M"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
|
||||||
|
capability() { # Return "Capture" if the device is a capture device
|
||||||
|
amixer $AMIXER_PARAMS -D $MIXER get $SCONTROL |
|
||||||
|
sed -n "s/ Capabilities:.*cvolume.*/Capture/p"
|
||||||
|
}
|
||||||
|
|
||||||
|
volume() {
|
||||||
|
amixer $AMIXER_PARAMS -D $MIXER get $SCONTROL $(capability)
|
||||||
|
}
|
||||||
|
|
||||||
|
format() {
|
||||||
|
|
||||||
|
perl_filter='if (/.*\[(\d+%)\] (\[(-?\d+.\d+dB)\] )?\[(on|off)\]/)'
|
||||||
|
perl_filter+='{CORE::say $4 eq "off" ? "MUTE" : "'
|
||||||
|
# If dB was selected, print that instead
|
||||||
|
perl_filter+=$([[ $STEP = *dB ]] && echo '$3' || echo '$1')
|
||||||
|
perl_filter+='"; exit}'
|
||||||
|
output=$(perl -ne "$perl_filter")
|
||||||
|
echo "$LABEL$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
|
||||||
|
case $BLOCK_BUTTON in
|
||||||
|
3) amixer $AMIXER_PARAMS -q -D $MIXER sset $SCONTROL $(capability) toggle ;; # right click, mute/unmute
|
||||||
|
4) amixer $AMIXER_PARAMS -q -D $MIXER sset $SCONTROL $(capability) ${STEP}+ unmute ;; # scroll up, increase
|
||||||
|
5) amixer $AMIXER_PARAMS -q -D $MIXER sset $SCONTROL $(capability) ${STEP}- unmute ;; # scroll down, decrease
|
||||||
|
esac
|
||||||
|
|
||||||
|
volume | format
|
172
scripts/volume-pipewire
Executable file
172
scripts/volume-pipewire
Executable file
@ -0,0 +1,172 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Displays the default device, volume, and mute status for i3blocks
|
||||||
|
|
||||||
|
set -a
|
||||||
|
|
||||||
|
AUDIO_HIGH_SYMBOL=${AUDIO_HIGH_SYMBOL:-' '}
|
||||||
|
|
||||||
|
AUDIO_MED_THRESH=${AUDIO_MED_THRESH:-50}
|
||||||
|
AUDIO_MED_SYMBOL=${AUDIO_MED_SYMBOL:-' '}
|
||||||
|
|
||||||
|
AUDIO_LOW_THRESH=${AUDIO_LOW_THRESH:-0}
|
||||||
|
AUDIO_LOW_SYMBOL=${AUDIO_LOW_SYMBOL:-' '}
|
||||||
|
|
||||||
|
AUDIO_MUTED_SYMBOL=${AUDIO_MUTED_SYMBOL:-' '}
|
||||||
|
|
||||||
|
AUDIO_DELTA=${AUDIO_DELTA:-5}
|
||||||
|
|
||||||
|
DEFAULT_COLOR=${DEFAULT_COLOR:-"#ffffff"}
|
||||||
|
MUTED_COLOR=${MUTED_COLOR:-"#a0a0a0"}
|
||||||
|
|
||||||
|
LONG_FORMAT=${LONG_FORMAT:-'${SYMB} ${VOL}% [${INDEX}:${NAME}]'}
|
||||||
|
SHORT_FORMAT=${SHORT_FORMAT:-'${SYMB} ${VOL}% [${INDEX}]'}
|
||||||
|
USE_ALSA_NAME=${USE_ALSA_NAME:-0}
|
||||||
|
USE_DESCRIPTION=${USE_DESCRIPTION:-0}
|
||||||
|
|
||||||
|
SUBSCRIBE=${SUBSCRIBE:-0}
|
||||||
|
|
||||||
|
MIXER=${MIXER:-""}
|
||||||
|
SCONTROL=${SCONTROL:-""}
|
||||||
|
|
||||||
|
while getopts F:Sf:adH:M:L:X:T:t:C:c:i:m:s:h opt; do
|
||||||
|
case "$opt" in
|
||||||
|
S) SUBSCRIBE=1 ;;
|
||||||
|
F) LONG_FORMAT="$OPTARG" ;;
|
||||||
|
f) SHORT_FORMAT="$OPTARG" ;;
|
||||||
|
a) USE_ALSA_NAME=1 ;;
|
||||||
|
d) USE_DESCRIPTION=1 ;;
|
||||||
|
H) AUDIO_HIGH_SYMBOL="$OPTARG" ;;
|
||||||
|
M) AUDIO_MED_SYMBOL="$OPTARG" ;;
|
||||||
|
L) AUDIO_LOW_SYMBOL="$OPTARG" ;;
|
||||||
|
X) AUDIO_MUTED_SYMBOL="$OPTARG" ;;
|
||||||
|
T) AUDIO_MED_THRESH="$OPTARG" ;;
|
||||||
|
t) AUDIO_LOW_THRESH="$OPTARG" ;;
|
||||||
|
C) DEFAULT_COLOR="$OPTARG" ;;
|
||||||
|
c) MUTED_COLOR="$OPTARG" ;;
|
||||||
|
i) AUDIO_INTERVAL="$OPTARG" ;;
|
||||||
|
m) MIXER="$OPTARG" ;;
|
||||||
|
s) SCONTROL="$OPTARG" ;;
|
||||||
|
h) printf \
|
||||||
|
"Usage: volume-pulseaudio [-S] [-F format] [-f format] [-p] [-a|-d] [-H symb] [-M symb]
|
||||||
|
[-L symb] [-X symb] [-T thresh] [-t thresh] [-C color] [-c color] [-i inter]
|
||||||
|
[-m mixer] [-s scontrol] [-h]
|
||||||
|
Options:
|
||||||
|
-F, -f\tOutput format (-F long format, -f short format) to use, with exposed variables:
|
||||||
|
\${SYMB}, \${VOL}, \${INDEX}, \${NAME}
|
||||||
|
-S\tSubscribe to volume events (requires persistent block, always uses long format)
|
||||||
|
-a\tUse ALSA name if possible
|
||||||
|
-d\tUse device description instead of name if possible
|
||||||
|
-H\tSymbol to use when audio level is high. Default: '$AUDIO_HIGH_SYMBOL'
|
||||||
|
-M\tSymbol to use when audio level is medium. Default: '$AUDIO_MED_SYMBOL'
|
||||||
|
-L\tSymbol to use when audio level is low. Default: '$AUDIO_LOW_SYMBOL'
|
||||||
|
-X\tSymbol to use when audio is muted. Default: '$AUDIO_MUTED_SYMBOL'
|
||||||
|
-T\tThreshold for medium audio level. Default: $AUDIO_MED_THRESH
|
||||||
|
-t\tThreshold for low audio level. Default: $AUDIO_LOW_THRESH
|
||||||
|
-C\tColor for non-muted audio. Default: $DEFAULT_COLOR
|
||||||
|
-c\tColor for muted audio. Default: $MUTED_COLOR
|
||||||
|
-i\tInterval size of volume increase/decrease. Default: $AUDIO_DELTA
|
||||||
|
-m\tUse the given mixer.
|
||||||
|
-s\tUse the given scontrol.
|
||||||
|
-h\tShow this help text
|
||||||
|
" && exit 0;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$MIXER" ]] ; then
|
||||||
|
MIXER="default"
|
||||||
|
if amixer -D pulse info >/dev/null 2>&1 ; then
|
||||||
|
MIXER="pulse"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$SCONTROL" ]] ; then
|
||||||
|
SCONTROL=$(amixer -D "$MIXER" scontrols | sed -n "s/Simple mixer control '\([^']*\)',0/\1/p" | head -n1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
CAPABILITY=$(amixer -D $MIXER get $SCONTROL | sed -n "s/ Capabilities:.*cvolume.*/Capture/p")
|
||||||
|
|
||||||
|
|
||||||
|
function move_sinks_to_new_default {
|
||||||
|
DEFAULT_SINK=$1
|
||||||
|
pactl list sink-inputs | grep 'Sink Input #' | grep -o '[0-9]\+' | while read SINK
|
||||||
|
do
|
||||||
|
pactl move-sink-input $SINK $DEFAULT_SINK
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_default_playback_device_next {
|
||||||
|
inc=${1:-1}
|
||||||
|
num_devices=$(pactl list sinks | grep -c Name:)
|
||||||
|
sink_arr=($(pactl list sinks | grep Name: | sed -r 's/\s+Name: (.+)/\1/'))
|
||||||
|
default_sink=$(pactl get-default-sink)
|
||||||
|
default_sink_index=$(for i in "${!sink_arr[@]}"; do if [[ "$default_sink" = "${sink_arr[$i]}" ]]; then echo "$i"; fi done)
|
||||||
|
default_sink_index=$(( ($default_sink_index + $num_devices + $inc) % $num_devices ))
|
||||||
|
default_sink=${sink_arr[$default_sink_index]}
|
||||||
|
pactl set-default-sink $default_sink
|
||||||
|
move_sinks_to_new_default $default_sink
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$BLOCK_BUTTON" in
|
||||||
|
1) set_default_playback_device_next ;;
|
||||||
|
2) amixer -q -D $MIXER sset $SCONTROL $CAPABILITY toggle ;;
|
||||||
|
3) set_default_playback_device_next -1 ;;
|
||||||
|
4) amixer -q -D $MIXER sset $SCONTROL $CAPABILITY $AUDIO_DELTA%+ ;;
|
||||||
|
5) amixer -q -D $MIXER sset $SCONTROL $CAPABILITY $AUDIO_DELTA%- ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
function print_format {
|
||||||
|
echo "$1" | envsubst '${SYMB}${VOL}${INDEX}${NAME}'
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_block {
|
||||||
|
ACTIVE=$(pactl list sinks | grep "State\: RUNNING" -B4 -A55 | grep "Name:\|Volume: \(front-left\|mono\)\|Mute:\|api.alsa.pcm.card = \|node.nick = ")
|
||||||
|
for Name in NAME MUTED VOL INDEX NICK; do
|
||||||
|
read $Name
|
||||||
|
done < <(echo "$ACTIVE")
|
||||||
|
INDEX=$(echo "$INDEX" | grep -o '".*"' | sed 's/"//g')
|
||||||
|
VOL=$(echo "$VOL" | grep -o "[0-9]*%" | head -1 )
|
||||||
|
VOL="${VOL%?}"
|
||||||
|
NAME=$(echo "$NICK" | grep -o '".*"' | sed 's/"//g')
|
||||||
|
|
||||||
|
if [[ $USE_ALSA_NAME == 1 ]] ; then
|
||||||
|
ALSA_NAME=$(pactl list sinks |\
|
||||||
|
awk '/^\s*\*/{f=1}/^\s*index:/{f=0}f' |\
|
||||||
|
grep "alsa.name\|alsa.mixer_name" |\
|
||||||
|
head -n1 |\
|
||||||
|
sed 's/.*= "\(.*\)".*/\1/')
|
||||||
|
NAME=${ALSA_NAME:-$NAME}
|
||||||
|
elif [[ $USE_DESCRIPTION == 1 ]] ; then
|
||||||
|
DESCRIPTION=$(pactl list sinks | grep "State\: RUNNING" -B4 -A55 | grep 'Description: ' | sed 's/^.*: //')
|
||||||
|
NAME=${DESCRIPTION:-$NAME}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $MUTED =~ "no" ]] ; then
|
||||||
|
SYMB=$AUDIO_HIGH_SYMBOL
|
||||||
|
[[ $VOL -le $AUDIO_MED_THRESH ]] && SYMB=$AUDIO_MED_SYMBOL
|
||||||
|
[[ $VOL -le $AUDIO_LOW_THRESH ]] && SYMB=$AUDIO_LOW_SYMBOL
|
||||||
|
COLOR=$DEFAULT_COLOR
|
||||||
|
else
|
||||||
|
SYMB=$AUDIO_MUTED_SYMBOL
|
||||||
|
COLOR=$MUTED_COLOR
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $ACTIVE = "" ]] ; then
|
||||||
|
echo "Sound inactive"
|
||||||
|
COLOR='#222225'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $SUBSCRIBE == 1 ]] ; then
|
||||||
|
print_format "$LONG_FORMAT"
|
||||||
|
else
|
||||||
|
print_format "$LONG_FORMAT"
|
||||||
|
print_format "$SHORT_FORMAT"
|
||||||
|
echo "$COLOR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_block
|
||||||
|
if [[ $SUBSCRIBE == 1 ]] ; then
|
||||||
|
while read -r EVENT; do
|
||||||
|
print_block
|
||||||
|
done < <(pactl subscribe | stdbuf -oL grep change)
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user