On my current voidlinux system I have no access to elogind and riverwm will just be restarted when I exit it (since it is watched over by a user service). My session is started by the display manager 'greetd' (which in turn runs tuigreet but that is not important here). So, to log out of the session - we do a search for the 'greetd' process and if we find it we search its _child_ processes which are the ones that we can kill without being a super user. If we kill the right process here, the session will close (since the 'watched' process exits and greetd just takes over again). This would be a little easier if we started riverwm through greetd directly but I like this indirection for stability (automatic service restarts), flexibility (I can stop the riverwm service independent of my session), and adaption (we can use Turnstile environment variables between my session services). So we just close all the processes that are children of greetd -- perhaps we accidentally catch a process which is _not_ the root session process run by greetd but we'll kill it nevertheless since all child processes might stop greetd from taking over (and they would be closed anyway when ending the session afaik). I have no linger enabled on my system so far (user processes staying enabled after log-out) and I do not know how that would interact with this method.
113 lines
3.6 KiB
Bash
Executable file
113 lines
3.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# A simple powermenu listing.
|
|
# Uses bemenu to display the powermenu on X11, Wayland and terminal.
|
|
|
|
#### Environment Variable Options ###
|
|
# Interface options
|
|
# POWERMENU_SHOW_ICONS=1
|
|
# POWERMENU_SHOW_TEXT=1
|
|
# POWERMENU_SHOW_UPTIME=1
|
|
# Command options
|
|
# POWERMENU_SHUTDOWN_CMD=""
|
|
# POWERMENU_REBOOT_CMD=""
|
|
# POWERMENU_LOCKSCREEN_CMD=""
|
|
# POWERMENU_LOGOUT_CMD=""
|
|
# POWERMENU_SUSPEND_CMD=""
|
|
# POWERMENU_HIBERNATE_CMD=""
|
|
# Command chooser options
|
|
# POWERMENU_PICKER_CMD=""
|
|
# POWERMENU_PICKER_OPTS=""
|
|
|
|
#### Menu Options ###
|
|
if [ "${POWERMENU_SHOW_TEXT:-0}" -eq 0 ] && [ "${POWERMENU_SHOW_ICONS:-1}" -eq 0 ]; then
|
|
echo "You disabled both text and icons for rofi-powermenu, nothing can be shown."
|
|
exit 1
|
|
elif [ "${POWERMENU_SHOW_ICONS:-1}" -eq 1 ]; then
|
|
power_off_btn="⏻"
|
|
reboot_btn=""
|
|
lock_btn=""
|
|
suspend_btn=""
|
|
hibernate_btn="⏾"
|
|
logout_btn=""
|
|
fi
|
|
if [ "${POWERMENU_SHOW_TEXT:-1}" -eq 1 ]; then
|
|
power_off_btn="${power_off_btn} Shut Down"
|
|
reboot_btn="${reboot_btn} Restart"
|
|
lock_btn="${lock_btn} Lock Screen"
|
|
suspend_btn="${suspend_btn} Suspend"
|
|
hibernate_btn="${hibernate_btn} Hibernate"
|
|
logout_btn="${logout_btn} Log Out"
|
|
fi
|
|
|
|
## SET PROMPT
|
|
if [ "${POWERMENU_SHOW_UPTIME:-1}" -eq 1 ]; then
|
|
prompt="Uptime $(uptime -p | sed -e 's/up //g') >"
|
|
else
|
|
prompt="Power >"
|
|
fi
|
|
|
|
selector_program="${POWERMENU_PICKER_CMD:-bemenu}"
|
|
selector_opts="${POWERMENU_PICKER_OPTS:--i}"
|
|
|
|
menu=$(printf "%s\n" "$lock_btn" "$suspend_btn" "$power_off_btn" "$reboot_btn" "$hibernate_btn" "$logout_btn")
|
|
# shellcheck disable=SC2086
|
|
result=$(printf "%s" "$menu" | $selector_program $selector_opts --prompt "$prompt")
|
|
|
|
# grep -a since it assumes with our nullcodes etc that this is a binary file
|
|
# grep -o to only leave the things we grep for
|
|
case "$result" in
|
|
"Shutdown" | "$power_off_btn")
|
|
if [ -n "$POWERMENU_SHUTDOWN_CMD" ]; then eval "$POWERMENU_SHUTDOWN_CMD"; else
|
|
if [ -x /usr/bin/systemctl ]; then
|
|
systemctl poweroff
|
|
else
|
|
sudo poweroff
|
|
fi
|
|
fi
|
|
;;
|
|
"Reboot" | "$reboot_btn")
|
|
if [ -n "$POWERMENU_REBOOT_CMD" ]; then eval "$POWERMENU_REBOOT_CMD"; else
|
|
if [ -x /usr/bin/systemctl ]; then
|
|
systemctl reboot
|
|
else
|
|
sudo reboot
|
|
fi
|
|
fi
|
|
;;
|
|
"Lockscreen" | "$lock_btn")
|
|
# Completely detach from the parent script
|
|
# If in/outputs are not redirected, rofi will wait for the forked process as well.
|
|
if [ -n "$POWERMENU_LOCKSCREEN_CMD" ]; then eval "$POWERMENU_LOCKSCREEN_CMD"; else
|
|
lockscreen
|
|
fi
|
|
;;
|
|
"Logout" | "$logout_btn")
|
|
if [ -n "$POWERMENU_LOGOUT_CMD" ]; then eval "$POWERMENU_LOGOUT_CMD"; else
|
|
command -v i3 >/dev/null 2>&1 && i3-msg exit
|
|
command -v riverctl >/dev/null 2>&1 && riverctl exit
|
|
# Try to heuristically find the program started by greetd and shut it down.
|
|
# Generally this will just be a 'pause' program on my system.
|
|
if command -v pgrep >/dev/null 2>&1 && pgrep greetd; then
|
|
kill $(pgrep -P "$(pgrep greetd | tr '\n' ',')" pause)
|
|
fi
|
|
fi
|
|
;;
|
|
"Suspend" | "$suspend_btn")
|
|
if [ -n "$POWERMENU_SUSPEND_CMD" ]; then eval "$POWERMENU_SUSPEND_CMD"; else
|
|
if [ -x /usr/bin/systemctl ]; then
|
|
systemctl suspend-then-hibernate
|
|
else
|
|
sudo zzz
|
|
fi
|
|
fi
|
|
;;
|
|
"Hibernate" | "$hibernate_btn")
|
|
if [ -n "$POWERMENU_HIBERNATE_CMD" ]; then eval "$POWERMENU_HIBERNATE_CMD"; else
|
|
if [ -x /usr/bin/systemctl ]; then
|
|
systemctl hibernate
|
|
else
|
|
sudo ZZZ
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|