Use rofi power menu
This commit is contained in:
parent
d7c4225359
commit
0f8550b990
|
@ -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
|
|
@ -130,7 +130,7 @@ top_panel.create = function(s)
|
|||
client.connect_signal("focus", change_panel_visibility)
|
||||
|
||||
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
|
||||
|
|
|
@ -162,7 +162,14 @@ keys.globalkeys = gears.table.join(
|
|||
{description = "Open Nautilus", group = "launcher"}
|
||||
),
|
||||
-- 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()
|
||||
awful.spawn("/home/user/.config/awesome/scripts/toggle_rofi.sh")
|
||||
end,
|
||||
|
@ -256,7 +263,7 @@ keys.globalkeys = gears.table.join(
|
|||
awful.key({modkey}, "Escape",
|
||||
function()
|
||||
-- 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,
|
||||
{description = "toggle exit screen", group = "hotkeys"}
|
||||
),
|
||||
|
|
|
@ -25,7 +25,6 @@ local pastel = {}
|
|||
pastel.initialize = function()
|
||||
-- Import components
|
||||
require("components.pastel.wallpaper")
|
||||
require("components.exit-screen")
|
||||
|
||||
-- Import panels
|
||||
local top_panel = require("components.pastel.top-panel")
|
||||
|
|
|
@ -31,7 +31,7 @@ apps = {
|
|||
local run_on_start_up = {
|
||||
"numlockx on",
|
||||
"nm-applet",
|
||||
"xcape -e \"Super_L=Super_L|Shift_L|F9\""
|
||||
"xcape -e \"Super_L=Super_L|XF86Launch5\" -t 5000"
|
||||
}
|
||||
|
||||
-- ===================================================================
|
||||
|
|
|
@ -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
|
|
@ -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>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", "<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 })
|
||||
|
|
|
@ -2,7 +2,7 @@ configuration {
|
|||
font: "SF Pro Rounded 13";
|
||||
show-icons: true;
|
||||
icon-theme: "Papirus";
|
||||
kb-cancel: "Super_L+Shift_L+F9,Escape";
|
||||
kb-cancel: "Super_L+XF86Launch5,Escape";
|
||||
combi-hide-mode-prefix: true;
|
||||
}
|
||||
@theme "~/.config/rofi/material-ocean.rasi"
|
||||
|
|
Loading…
Reference in New Issue