2023-05-16 09:59:04 +01:00
|
|
|
#!/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/>.
|
|
|
|
|
|
|
|
# modified to work with latest rofi update by joekamprad <joekamprad@endeavouros.com>
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# BEGIN CONFIG #
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
# Use a custom lock script
|
|
|
|
#LOCKSCRIPT="i3lock-extra -m pixelize"
|
|
|
|
|
|
|
|
# Colors: FG (foreground), BG (background), HL (highlighted)
|
|
|
|
FG_COLOR="#bbbbbb"
|
|
|
|
BG_COLOR="#111111"
|
|
|
|
HLFG_COLOR="#111111"
|
|
|
|
HLBG_COLOR="#bbbbbb"
|
|
|
|
BORDER_COLOR="#222222"
|
|
|
|
|
|
|
|
# Options not related to colors (most rofi options do not work anymore)
|
|
|
|
#ROFI_OPTIONS=(-theme ~/.dotfiles/rofi/powermenu.rasi)
|
|
|
|
# Zenity options
|
|
|
|
ZENITY_TITLE="Power Menu"
|
|
|
|
ZENITY_TEXT="Action:"
|
|
|
|
ZENITY_OPTIONS=(--column= --hide-header)
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# END CONFIG #
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
# Whether to ask for user's confirmation
|
|
|
|
enable_confirmation=false
|
|
|
|
|
|
|
|
# Preferred launcher if both are available
|
|
|
|
preferred_launcher="rofi"
|
|
|
|
|
|
|
|
usage="$(basename "$0") [-h] [-c] [-p name] -- display a menu for shutdown, reboot, lock etc.
|
|
|
|
|
|
|
|
where:
|
2023-06-27 15:11:01 +01:00
|
|
|
-h show this help text
|
|
|
|
-c ask for user confirmation
|
|
|
|
-p preferred launcher (rofi or zenity)
|
2023-05-16 09:59:04 +01:00
|
|
|
|
|
|
|
This script depends on:
|
2023-06-27 15:11:01 +01:00
|
|
|
- systemd,
|
|
|
|
- rofi or zenity."
|
2023-05-16 09:59:04 +01:00
|
|
|
|
|
|
|
# Check whether the user-defined launcher is valid
|
|
|
|
launcher_list=(rofi zenity)
|
|
|
|
function check_launcher() {
|
2023-06-27 15:11:01 +01:00
|
|
|
if [[ ! "${launcher_list[@]}" =~ (^|[[:space:]])"$1"($|[[:space:]]) ]]; then
|
2023-05-16 09:59:04 +01:00
|
|
|
echo "Supported launchers: ${launcher_list[*]}"
|
|
|
|
exit 1
|
2023-06-27 15:11:01 +01:00
|
|
|
else
|
2023-05-16 09:59:04 +01:00
|
|
|
# Get array with unique elements and preferred launcher first
|
|
|
|
# Note: uniq expects a sorted list, so we cannot use it
|
|
|
|
i=1
|
2023-06-27 15:11:01 +01:00
|
|
|
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
|
2023-05-16 09:59:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Parse CLI arguments
|
|
|
|
while getopts "hcp:" option; do
|
2023-06-27 15:11:01 +01:00
|
|
|
case "$option" in
|
|
|
|
h) echo "$usage"
|
|
|
|
exit 0
|
|
|
|
;;
|
2023-05-16 09:59:04 +01:00
|
|
|
c) enable_confirmation=true
|
2023-06-27 15:11:01 +01:00
|
|
|
;;
|
|
|
|
p) preferred_launcher="$OPTARG"
|
|
|
|
check_launcher "$preferred_launcher"
|
|
|
|
;;
|
2023-05-16 09:59:04 +01:00
|
|
|
*) exit 1
|
2023-06-27 15:11:01 +01:00
|
|
|
;;
|
|
|
|
esac
|
2023-05-16 09:59:04 +01:00
|
|
|
done
|
|
|
|
|
|
|
|
# Check whether a command exists
|
|
|
|
function command_exists() {
|
2023-06-27 15:11:01 +01:00
|
|
|
command -v "$1" &> /dev/null 2>&1
|
2023-05-16 09:59:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# systemctl required
|
|
|
|
if ! command_exists systemctl ; then
|
2023-06-27 15:11:01 +01:00
|
|
|
exit 1
|
2023-05-16 09:59:04 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
# menu defined as an associative array
|
|
|
|
typeset -A menu
|
|
|
|
|
|
|
|
# Menu with keys/commands
|
|
|
|
|
|
|
|
menu=(
|
2023-06-27 15:11:01 +01:00
|
|
|
[ Shutdown]="systemctl poweroff"
|
|
|
|
[ Reboot]="systemctl reboot"
|
|
|
|
[ Suspend]="systemctl suspend"
|
|
|
|
[ Hibernate]="systemctl hibernate"
|
2023-07-02 16:50:25 +01:00
|
|
|
[ Lock]="xfce4-screensaver-command --lock"
|
|
|
|
[ Logout]=""
|
2023-06-27 15:11:01 +01:00
|
|
|
[ Cancel]=""
|
2023-05-16 09:59:04 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
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() {
|
2023-06-27 15:11:01 +01:00
|
|
|
if [[ "$1" == "rofi" ]]; then
|
|
|
|
rofi_colors=(-bc "$BORDER_COLOR" -bg "$BG_COLOR" -fg "$FG_COLOR" \
|
|
|
|
-hlfg "$HLFG_COLOR" -hlbg "$HLBG_COLOR")
|
2023-05-16 09:59:04 +01:00
|
|
|
launcher_exe="rofi"
|
2023-06-27 15:11:01 +01:00
|
|
|
launcher_options=(-dmenu -i -lines "$menu_nrows" -p "$ROFI_TEXT" \
|
|
|
|
"$rofi_colors" "${ROFI_OPTIONS[@]}")
|
|
|
|
elif [[ "$1" == "zenity" ]]; then
|
2023-05-16 09:59:04 +01:00
|
|
|
launcher_exe="zenity"
|
2023-06-27 15:11:01 +01:00
|
|
|
launcher_options=(--list --title="$ZENITY_TITLE" --text="$ZENITY_TEXT" \
|
2023-05-16 09:59:04 +01:00
|
|
|
"${ZENITY_OPTIONS[@]}")
|
2023-06-27 15:11:01 +01:00
|
|
|
fi
|
2023-05-16 09:59:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for l in "${launcher_list[@]}"; do
|
2023-06-27 15:11:01 +01:00
|
|
|
if command_exists "$l" ; then
|
|
|
|
prepare_launcher "$l"
|
2023-05-16 09:59:04 +01:00
|
|
|
break
|
2023-06-27 15:11:01 +01:00
|
|
|
fi
|
2023-05-16 09:59:04 +01:00
|
|
|
done
|
|
|
|
|
|
|
|
# No launcher available
|
2023-06-27 15:11:01 +01:00
|
|
|
if [[ -z "$launcher_exe" ]]; then
|
|
|
|
exit 1
|
2023-05-16 09:59:04 +01:00
|
|
|
fi
|
|
|
|
|
2023-06-27 15:11:01 +01:00
|
|
|
launcher=("$launcher_exe" "${launcher_options[@]}")
|
2023-05-16 09:59:04 +01:00
|
|
|
selection="$(printf '%s\n' "${!menu[@]}" | sort | "${launcher[@]}")"
|
|
|
|
|
|
|
|
function ask_confirmation() {
|
2023-06-27 15:11:01 +01:00
|
|
|
if [ "$launcher_exe" == "rofi" ]; then
|
2023-05-16 09:59:04 +01:00
|
|
|
confirmed=$(echo -e "Yes\nNo" | rofi -dmenu -i -lines 2 -p "${selection}?" \
|
2023-06-27 15:11:01 +01:00
|
|
|
"$rofi_colors" "${ROFI_OPTIONS[@]}")
|
|
|
|
[ "$confirmed" == "Yes" ] && confirmed=0
|
|
|
|
elif [ "$launcher_exe" == "zenity" ]; then
|
2023-05-16 09:59:04 +01:00
|
|
|
zenity --question --text "Are you sure you want to ${selection,,}?"
|
|
|
|
confirmed=$?
|
2023-06-27 15:11:01 +01:00
|
|
|
fi
|
2023-05-16 09:59:04 +01:00
|
|
|
|
2023-06-27 15:11:01 +01:00
|
|
|
if [ "$confirmed" == 0 ]; then
|
|
|
|
"${menu[${selection}]}"
|
|
|
|
fi
|
2023-05-16 09:59:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if [[ $? -eq 0 && ! -z ${selection} ]]; then
|
2023-06-27 15:11:01 +01:00
|
|
|
if [[ "$enable_confirmation" = true && \
|
|
|
|
${menu_confirm} =~ (^|[[:space:]])"$selection"($|[[:space:]]) ]]; then
|
|
|
|
ask_confirmation
|
|
|
|
else
|
|
|
|
"${menu[${selection}]}"
|
|
|
|
fi
|
2023-05-16 09:59:04 +01:00
|
|
|
fi
|