Use rofi power menu

This commit is contained in:
Thomas Avé 2022-07-27 13:22:39 +02:00
parent d7c4225359
commit 0f8550b990
8 changed files with 256 additions and 231 deletions

View File

@ -1,225 +0,0 @@
-- ███████╗██╗ ██╗██╗████████╗ ███████╗ ██████╗██████╗ ███████╗███████╗███╗ ██╗
-- ██╔════╝╚██╗██╔╝██║╚══██╔══╝ ██╔════╝██╔════╝██╔══██╗██╔════╝██╔════╝████╗ ██║
-- █████╗ ╚███╔╝ ██║ ██║ ███████╗██║ ██████╔╝█████╗ █████╗ ██╔██╗ ██║
-- ██╔══╝ ██╔██╗ ██║ ██║ ╚════██║██║ ██╔══██╗██╔══╝ ██╔══╝ ██║╚██╗██║
-- ███████╗██╔╝ ██╗██║ ██║ ███████║╚██████╗██║ ██║███████╗███████╗██║ ╚████║
-- ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═══╝
-- ===================================================================
-- Initialization
-- ===================================================================
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local clickable_container = require("widgets.clickable-container")
local dpi = beautiful.xresources.apply_dpi
local ICON_DIR = gears.filesystem.get_configuration_dir() .. "/icons/exit-screen/" .. beautiful.name .. "/"
-- define module table
local exit_screen = {}
-- ===================================================================
-- Appearance
-- ===================================================================
local icon_size = dpi(90)
local build_button = function(icon)
local button = wibox.widget {
wibox.widget {
wibox.widget {
wibox.widget {
image = icon,
widget = wibox.widget.imagebox
},
top = dpi(16),
bottom = dpi(16),
left = dpi(16),
right = dpi(16),
widget = wibox.container.margin
},
shape = gears.shape.circle,
forced_width = icon_size,
forced_height = icon_size,
widget = clickable_container
},
left = dpi(24),
right = dpi(24),
widget = wibox.container.margin
}
return button
end
-- ===================================================================
-- Functionality
-- ===================================================================
local exit_screen_grabber
local function suspend_command()
exit_screen.hide()
awful.spawn.with_shell(apps.lock .. " & systemctl suspend")
end
local function exit_command()
awesome.quit()
end
local function lock_command()
exit_screen.hide()
awful.spawn.with_shell("sleep 1 && " .. apps.lock)
end
local function poweroff_command()
awful.spawn.with_shell("poweroff")
awful.keygrabber.stop(exit_screen_grabber)
end
local function reboot_command()
awful.spawn.with_shell("reboot")
awful.keygrabber.stop(exit_screen_grabber)
end
local poweroff = build_button(ICON_DIR .. "power.png", "Shutdown")
poweroff:connect_signal(
"button::release",
function()
poweroff_command()
end
)
local reboot = build_button(ICON_DIR .. "restart.png", "Restart")
reboot:connect_signal(
"button::release",
function()
reboot_command()
end
)
local suspend = build_button(ICON_DIR .. "sleep.png", "Sleep")
suspend:connect_signal(
"button::release",
function()
suspend_command()
end
)
local exit = build_button(ICON_DIR .. "logout.png", "Logout")
exit:connect_signal(
"button::release",
function()
exit_command()
end
)
local lock = build_button(ICON_DIR .. "lock.png", "Lock")
lock:connect_signal(
"button::release",
function()
lock_command()
end
)
-- subscribe to the show_exit_screen signal
-- show the exit screen when signal is broadcasted
awesome.connect_signal("show_exit_screen",
function()
exit_screen_grabber = awful.keygrabber.run(
function(_, key, event)
if event == "release" then
return
end
if key == "s" then
suspend_command()
elseif key == "e" then
exit_command()
elseif key == "l" then
lock_command()
elseif key == "p" then
poweroff_command()
elseif key == "r" then
reboot_command()
elseif key == "Escape" or key == "q" or key == "x" then
exit_screen.hide()
end
end
)
exit_screen.widget.visible = true
end
)
-- hide exit screen
function exit_screen.hide()
awful.keygrabber.stop(exit_screen_grabber)
exit_screen.widget.visible = false
end
-- ===================================================================
-- Create Widget
-- ===================================================================
local screen_geometry = awful.screen.focused().geometry
-- Create the widget
exit_screen.widget = wibox({
x = screen_geometry.x,
y = screen_geometry.y,
visible = false,
ontop = true,
type = "splash",
height = screen_geometry.height,
width = screen_geometry.width
})
exit_screen.widget:buttons(
gears.table.join(
-- Middle click - Hide exit_screen
awful.button({}, 2,
function()
exit_screen.hide()
end
),
-- Right click - Hide exit_screen
awful.button({}, 3,
function()
exit_screen.hide()
end
)
)
)
-- Item placement
exit_screen.widget:setup {
nil,
{
nil,
{
poweroff,
reboot,
suspend,
exit,
lock,
layout = wibox.layout.fixed.horizontal
},
nil,
expand = "none",
layout = wibox.layout.align.horizontal
},
nil,
expand = "none",
layout = wibox.layout.align.vertical
}
return exit_screen

View File

@ -130,7 +130,7 @@ top_panel.create = function(s)
client.connect_signal("focus", change_panel_visibility) client.connect_signal("focus", change_panel_visibility)
updates_indicator:connect_signal("button::press", function(c, _, _, button) updates_indicator:connect_signal("button::press", function(c, _, _, button)
awful.spawn('bash -c "WINIT_X11_SCALE_FACTOR=1 alacritty -e bash -c \"yay ; echo \'\\nDone, press any key to exit...\' ; read\""') awful.spawn('alacritty -e bash -c "yay ; echo \'\nDone, press any key to exit...\' ; read"')
end) end)
end end

View File

@ -162,7 +162,14 @@ keys.globalkeys = gears.table.join(
{description = "Open Nautilus", group = "launcher"} {description = "Open Nautilus", group = "launcher"}
), ),
-- launch rofi -- launch rofi
awful.key({modkey, altkey}, "F9", awful.key({modkey}, "XF86Launch5",
function()
awful.spawn("/home/user/.config/awesome/scripts/toggle_rofi.sh")
end,
{description = "application launcher", group = "launcher"}
),
-- launch rofi
awful.key({modkey}, "d",
function() function()
awful.spawn("/home/user/.config/awesome/scripts/toggle_rofi.sh") awful.spawn("/home/user/.config/awesome/scripts/toggle_rofi.sh")
end, end,
@ -256,7 +263,7 @@ keys.globalkeys = gears.table.join(
awful.key({modkey}, "Escape", awful.key({modkey}, "Escape",
function() function()
-- emit signal to show the exit screen -- emit signal to show the exit screen
awesome.emit_signal("show_exit_screen") awful.util.spawn("rofi -show power-menu -modi power-menu:~/.config/awesome/scripts/rofi-power-menu")
end, end,
{description = "toggle exit screen", group = "hotkeys"} {description = "toggle exit screen", group = "hotkeys"}
), ),

View File

@ -25,7 +25,6 @@ local pastel = {}
pastel.initialize = function() pastel.initialize = function()
-- Import components -- Import components
require("components.pastel.wallpaper") require("components.pastel.wallpaper")
require("components.exit-screen")
-- Import panels -- Import panels
local top_panel = require("components.pastel.top-panel") local top_panel = require("components.pastel.top-panel")

View File

@ -31,7 +31,7 @@ apps = {
local run_on_start_up = { local run_on_start_up = {
"numlockx on", "numlockx on",
"nm-applet", "nm-applet",
"xcape -e \"Super_L=Super_L|Shift_L|F9\"" "xcape -e \"Super_L=Super_L|XF86Launch5\" -t 5000"
} }
-- =================================================================== -- ===================================================================

240
awesome/scripts/rofi-power-menu Executable file
View File

@ -0,0 +1,240 @@
#!/usr/bin/env bash
# This script defines just a mode for rofi instead of being a self-contained
# executable that launches rofi by itself. This makes it more flexible than
# running rofi inside this script as now the user can call rofi as one pleases.
# For instance:
#
# rofi -show powermenu -modi powermenu:./rofi-power-menu
#
# See README.md for more information.
set -e
set -u
# All supported choices
all=(shutdown reboot suspend hibernate logout lockscreen)
# By default, show all (i.e., just copy the array)
show=("${all[@]}")
declare -A texts
texts[lockscreen]="lock screen"
texts[switchuser]="switch user"
texts[logout]="log out"
texts[suspend]="suspend"
texts[hibernate]="hibernate"
texts[reboot]="reboot"
texts[shutdown]="shut down"
declare -A icons
icons[lockscreen]="system-lock-screen"
icons[switchuser]="\uf518"
icons[logout]="gnome-logout"
icons[suspend]="system-suspend"
icons[hibernate]="system-hibernate"
icons[reboot]="system-reboot"
icons[shutdown]="system-shutdown"
icons[cancel]="advert-block"
declare -A actions
actions[lockscreen]="loginctl lock-session ${XDG_SESSION_ID-}"
#actions[switchuser]="???"
actions[logout]="loginctl terminate-session ${XDG_SESSION_ID-}"
actions[suspend]="systemctl suspend"
actions[hibernate]="systemctl hibernate"
actions[reboot]="systemctl reboot"
actions[shutdown]="systemctl poweroff"
# By default, ask for confirmation for actions that are irreversible
confirmations=(reboot shutdown logout)
# By default, no dry run
dryrun=false
showsymbols=true
function check_valid {
option="$1"
shift 1
for entry in "${@}"
do
if [ -z "${actions[$entry]+x}" ]
then
echo "Invalid choice in $1: $entry" >&2
exit 1
fi
done
}
# Parse command-line options
parsed=$(getopt --options=h --longoptions=help,dry-run,confirm:,choices:,choose:,symbols,no-symbols --name "$0" -- "$@")
if [ $? -ne 0 ]; then
echo 'Terminating...' >&2
exit 1
fi
eval set -- "$parsed"
unset parsed
while true; do
case "$1" in
"-h"|"--help")
echo "rofi-power-menu - a power menu mode for Rofi"
echo
echo "Usage: rofi-power-menu [--choices CHOICES] [--confirm CHOICES]"
echo " [--choose CHOICE] [--dry-run] [--symbols|--no-symbols]"
echo
echo "Use with Rofi in script mode. For instance, to ask for shutdown or reboot:"
echo
echo " rofi -show menu -modi \"menu:rofi-power-menu --choices=shutdown/reboot\""
echo
echo "Available options:"
echo " --dry-run Don't perform the selected action but print it to stderr."
echo " --choices CHOICES Show only the selected choices in the given order. Use / "
echo " as the separator. Available choices are lockscreen, logout,"
echo " suspend, hibernate, reboot and shutdown. By default, all"
echo " available choices are shown."
echo " --confirm CHOICES Require confirmation for the gives choices only. Use / as"
echo " the separator. Available choices are lockscreen, logout,"
echo " suspend, hibernate, reboot and shutdown. By default, only"
echo " irreversible actions logout, reboot and shutdown require"
echo " confirmation."
echo " --choose CHOICE Preselect the given choice and only ask for a confirmation"
echo " (if confirmation is set to be requested). It is strongly"
echo " recommended to combine this option with --confirm=CHOICE"
echo " if the choice wouldn't require confirmation by default."
echo " Available choices are lockscreen, logout, suspend,"
echo " hibernate, reboot and shutdown."
echo " --[no-]symbols Show Unicode symbols or not. Requires a font with support"
echo " for the symbols. Use, for instance, fonts from the"
echo " Nerdfonts collection. By default, they are shown"
echo " -h,--help Show this help text."
exit 0
;;
"--dry-run")
dryrun=true
shift 1
;;
"--confirm")
IFS='/' read -ra confirmations <<< "$2"
check_valid "$1" "${confirmations[@]}"
shift 2
;;
"--choices")
IFS='/' read -ra show <<< "$2"
check_valid "$1" "${show[@]}"
shift 2
;;
"--choose")
# Check that the choice is valid
check_valid "$1" "$2"
selectionID="$2"
shift 2
;;
"--symbols")
showsymbols=true
shift 1
;;
"--no-symbols")
showsymbols=false
shift 1
;;
"--")
shift
break
;;
*)
echo "Internal error" >&2
exit 1
;;
esac
done
# Define the messages after parsing the CLI options so that it is possible to
# configure them in the future.
function write_message {
text="<span font_size=\"medium\">$1</span>"
echo -n "$text"
}
function print_selection {
echo -e "$1" | $(read -r -d '' entry; echo "echo $entry")
}
declare -A messages
declare -A confirmationMessages
for entry in "${all[@]}"
do
messages[$entry]=$(write_message "${texts[$entry]^}")
done
for entry in "${all[@]}"
do
confirmationMessages[$entry]=$(write_message "Yes, ${texts[$entry]}")
done
confirmationMessages[cancel]=$(write_message "No, cancel")
if [ $# -gt 0 ]
then
# If arguments given, use those as the selection
selection="${@}"
else
# Otherwise, use the CLI passed choice if given
if [ -n "${selectionID+x}" ]
then
selection="${messages[$selectionID]}"
fi
fi
# Don't allow custom entries
echo -e "\0no-custom\x1ftrue"
# Use markup
echo -e "\0markup-rows\x1ftrue"
if [ -z "${selection+x}" ]
then
echo -e "\0prompt\x1fPower menu"
for entry in "${show[@]}"
do
echo -e "${messages[$entry]}\0icon\x1f${icons[$entry]}"
done
else
for entry in "${show[@]}"
do
if [ "$selection" = "$(print_selection "${messages[$entry]}")" ]
then
# Check if the selected entry is listed in confirmation requirements
for confirmation in "${confirmations[@]}"
do
if [ "$entry" = "$confirmation" ]
then
# Ask for confirmation
echo -e "\0prompt\x1fAre you sure"
echo -e "${confirmationMessages[$entry]}\0icon\x1f${icons[$entry]}"
echo -e "${confirmationMessages[cancel]}\0icon\x1f${icons[cancel]}"
exit 0
fi
done
# If not, then no confirmation is required, so mark confirmed
selection=$(print_selection "${confirmationMessages[$entry]}")
fi
if [ "$selection" = "$(print_selection "${confirmationMessages[$entry]}")" ]
then
if [ $dryrun = true ]
then
# Tell what would have been done
echo "Selected: $entry" >&2
else
# Perform the action
${actions[$entry]}
fi
exit 0
fi
if [ "$selection" = "$(print_selection "${confirmationMessages[cancel]}")" ]
then
# Do nothing
exit 0
fi
done
# The selection didn't match anything, so raise an error
echo "Invalid selection: $selection" >&2
exit 1
fi

View File

@ -8,3 +8,7 @@ vim.api.nvim_set_keymap("n", "<leader><space>", ":noh<cr>", { noremap = true, si
vim.api.nvim_set_keymap("n", "<leader>t", ":NvimTreeFindFileToggle<cr>", { noremap = true, silent = true }) vim.api.nvim_set_keymap("n", "<leader>t", ":NvimTreeFindFileToggle<cr>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("n", "<leader>a", "<C-A>", { noremap = true, silent = true }) vim.api.nvim_set_keymap("n", "<leader>a", "<C-A>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("n", "<leader>x", "<C-X>", { noremap = true, silent = true }) vim.api.nvim_set_keymap("n", "<leader>x", "<C-X>", { noremap = true, silent = true })
-- vim.api.nvim_set_keymap("n", "<S-h>x", "<C-h>", { noremap = true, silent = true })
-- vim.api.nvim_set_keymap("n", "<S-j>x", "<C-j>", { noremap = true, silent = true })
-- vim.api.nvim_set_keymap("n", "<S-k>x", "<C-k>", { noremap = true, silent = true })
-- vim.api.nvim_set_keymap("n", "<S-l>x", "<C-l>", { noremap = true, silent = true })

View File

@ -2,7 +2,7 @@ configuration {
font: "SF Pro Rounded 13"; font: "SF Pro Rounded 13";
show-icons: true; show-icons: true;
icon-theme: "Papirus"; icon-theme: "Papirus";
kb-cancel: "Super_L+Shift_L+F9,Escape"; kb-cancel: "Super_L+XF86Launch5,Escape";
combi-hide-mode-prefix: true; combi-hide-mode-prefix: true;
} }
@theme "~/.config/rofi/material-ocean.rasi" @theme "~/.config/rofi/material-ocean.rasi"