mirror of
https://github.com/imgurbot12/rmenu.git
synced 2024-11-10 11:33:48 +01:00
feat: move simple plugins to shell-script w/ new rmenu-build tool
This commit is contained in:
parent
1335477c3f
commit
faa7fea0fd
@ -5,8 +5,6 @@ members = [
|
|||||||
"rmenu-plugin",
|
"rmenu-plugin",
|
||||||
"plugin-run",
|
"plugin-run",
|
||||||
"plugin-desktop",
|
"plugin-desktop",
|
||||||
"plugin-audio",
|
|
||||||
"plugin-network",
|
"plugin-network",
|
||||||
"plugin-window",
|
"plugin-window",
|
||||||
"plugin-powermenu",
|
|
||||||
]
|
]
|
||||||
|
3
Makefile
3
Makefile
@ -17,11 +17,11 @@ install: build deploy
|
|||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
mkdir -p ${DEST}
|
mkdir -p ${DEST}
|
||||||
|
cp -vfr other-plugins/* ${DEST}/.
|
||||||
cp -vf ./target/release/rmenu ${INSTALL}/rmenu
|
cp -vf ./target/release/rmenu ${INSTALL}/rmenu
|
||||||
cp -vf ./target/release/rmenu-build ${INSTALL}/rmenu-build
|
cp -vf ./target/release/rmenu-build ${INSTALL}/rmenu-build
|
||||||
cp -vf ./target/release/desktop ${DEST}/rmenu-desktop
|
cp -vf ./target/release/desktop ${DEST}/rmenu-desktop
|
||||||
cp -vf ./target/release/run ${DEST}/rmenu-run
|
cp -vf ./target/release/run ${DEST}/rmenu-run
|
||||||
cp -vf ./target/release/audio ${DEST}/rmenu-audio
|
|
||||||
cp -vf ./target/release/network ${DEST}/rmenu-network
|
cp -vf ./target/release/network ${DEST}/rmenu-network
|
||||||
cp -vf ./target/release/window ${DEST}/rmenu-window
|
cp -vf ./target/release/window ${DEST}/rmenu-window
|
||||||
cp -vf ./rmenu/public/config.yaml ${DEST}/config.yaml
|
cp -vf ./rmenu/public/config.yaml ${DEST}/config.yaml
|
||||||
@ -35,6 +35,5 @@ build-rmenu:
|
|||||||
build-plugins:
|
build-plugins:
|
||||||
${CARGO} build -p run ${FLAGS}
|
${CARGO} build -p run ${FLAGS}
|
||||||
${CARGO} build -p desktop ${FLAGS}
|
${CARGO} build -p desktop ${FLAGS}
|
||||||
${CARGO} build -p audio ${FLAGS}
|
|
||||||
${CARGO} build -p network ${FLAGS}
|
${CARGO} build -p network ${FLAGS}
|
||||||
${CARGO} build -p window ${FLAGS}
|
${CARGO} build -p window ${FLAGS}
|
||||||
|
17
other-plugins/pactl-audio.sh
Executable file
17
other-plugins/pactl-audio.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#/bin/sh
|
||||||
|
|
||||||
|
get_sinks() {
|
||||||
|
sinks=`pactl list sinks | grep -e 'Sink' -e 'Name' -e 'Description' | nl -s '>'`
|
||||||
|
default=`pactl get-default-sink`
|
||||||
|
for i in `seq 1 3 $(echo "$sinks" | wc -l)`; do
|
||||||
|
sink=`echo "$sinks" | grep "$i>" | cut -d '#' -f2`
|
||||||
|
name=`echo "$sinks" | grep "$(expr $i + 1)>" | cut -d ':' -f2 | xargs echo -n`
|
||||||
|
desc=`echo "$sinks" | grep "$(expr $i + 2)>" | cut -d ':' -f2 | xargs echo -n`
|
||||||
|
if [ "$name" = "$default" ]; then
|
||||||
|
desc="* $desc"
|
||||||
|
fi
|
||||||
|
rmenu-build entry -n "$desc" -a "`rmenu-build action "pactl set-default-sink $sink"`"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
get_sinks
|
65
other-plugins/powermenu.sh
Executable file
65
other-plugins/powermenu.sh
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SELF=`realpath $0`
|
||||||
|
THEME=`realpath "$(dirname $0)/themes/powermenu.css"`
|
||||||
|
RMENU=${RMENU:-"rmenu"}
|
||||||
|
|
||||||
|
options() {
|
||||||
|
rmenu-build options \
|
||||||
|
-t $THEME \
|
||||||
|
-n ArrowRight -p ArrowLeft \
|
||||||
|
-w 550 -h 150 -M 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#: desc => generate confirmation entries
|
||||||
|
#: usage => $cmd $name?
|
||||||
|
confirm() {
|
||||||
|
cmd=$1
|
||||||
|
name="${2:-"Confirm"}"
|
||||||
|
options
|
||||||
|
rmenu-build entry -n "Cancel" -I "" -a "`rmenu-build action -m echo "$name Cancelled"`"
|
||||||
|
rmenu-build entry -n "$name" -I "" -a "`rmenu-build action "$cmd"`"
|
||||||
|
}
|
||||||
|
|
||||||
|
#: desc => generate non-confirm entry
|
||||||
|
#: usage => $icon $name $cmd
|
||||||
|
gen_direct() {
|
||||||
|
rmenu-build entry -n "$2" -I "$1" -a "`rmenu-build action "$3"`"
|
||||||
|
}
|
||||||
|
|
||||||
|
#: desc => generate confirmation entry
|
||||||
|
#: usage => $icon $name $cmd
|
||||||
|
gen_confirm() {
|
||||||
|
rmenu-build entry -n "$2" -I "$1" -a "`rmenu-build action "$SELF confirm '$2:$3'"`"
|
||||||
|
}
|
||||||
|
|
||||||
|
#: desc => generate action-entry
|
||||||
|
#: usage => $icon $name $command $do-confirm
|
||||||
|
action() {
|
||||||
|
icon="$1"
|
||||||
|
name="$2"
|
||||||
|
cmd="$3"
|
||||||
|
confirm="$4"
|
||||||
|
[ -z "$confirm" ] \
|
||||||
|
&& gen_direct "$icon" "$name" "$cmd" \
|
||||||
|
|| gen_confirm "$icon" "$name" "$cmd"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
"list")
|
||||||
|
confirm="$2"
|
||||||
|
options
|
||||||
|
action "⏻" "Shutdown" "systemctl poweroff" "$2"
|
||||||
|
action "" "Reboot" "systemctl reboot" "$2"
|
||||||
|
action "⏾" "Suspend" "systemctl suspend" "$2"
|
||||||
|
action "" "Log Out" "sway exit" "$2"
|
||||||
|
;;
|
||||||
|
"confirm")
|
||||||
|
name=`echo $2 | cut -d ':' -f1`
|
||||||
|
action=`echo $2 | cut -d ':' -f2`
|
||||||
|
confirm "$action" "$name" | $RMENU
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 <list|confirm> <args...>" && exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@ -1,14 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "audio"
|
|
||||||
version = "0.0.1"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = { version = "4.3.21", features = ["derive"] }
|
|
||||||
env_logger = "0.10.0"
|
|
||||||
log = "0.4.19"
|
|
||||||
rmenu-plugin = { version = "0.0.1", path = "../rmenu-plugin" }
|
|
||||||
serde_json = "1.0.104"
|
|
||||||
thiserror = "1.0.44"
|
|
@ -1,43 +0,0 @@
|
|||||||
use clap::{Parser, Subcommand};
|
|
||||||
use rmenu_plugin::Entry;
|
|
||||||
|
|
||||||
mod pulse;
|
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
|
||||||
pub enum Commands {
|
|
||||||
ListSinks,
|
|
||||||
SetDefaultSink { sink: u32 },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[command(author, version, about, long_about = None)]
|
|
||||||
#[command(propagate_version = true)]
|
|
||||||
pub struct Cli {
|
|
||||||
#[clap(subcommand)]
|
|
||||||
command: Option<Commands>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), pulse::PulseError> {
|
|
||||||
let cli = Cli::parse();
|
|
||||||
let exe = std::env::current_exe()?.to_str().unwrap().to_string();
|
|
||||||
|
|
||||||
let command = cli.command.unwrap_or(Commands::ListSinks);
|
|
||||||
match command {
|
|
||||||
Commands::ListSinks => {
|
|
||||||
let sinks = pulse::get_sinks()?;
|
|
||||||
for sink in sinks {
|
|
||||||
let star = sink.default.then(|| "* ").unwrap_or("");
|
|
||||||
let desc = format!("{star}{}", sink.description);
|
|
||||||
let exec = format!("{exe} set-default-sink {}", sink.index);
|
|
||||||
let entry = Entry::new(&desc, &exec, None);
|
|
||||||
println!("{}", serde_json::to_string(&entry).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Commands::SetDefaultSink { sink } => {
|
|
||||||
let sinkstr = format!("{sink}");
|
|
||||||
pulse::set_default_sink(&sinkstr)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use std::process::{Command, ExitStatus, Stdio};
|
|
||||||
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
static PACTL: &'static str = "pactl";
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum PulseError {
|
|
||||||
#[error("Invalid Status")]
|
|
||||||
InvalidStatus(ExitStatus),
|
|
||||||
#[error("Cannot Read Command Output")]
|
|
||||||
InvalidStdout,
|
|
||||||
#[error("Invalid Output Encoding")]
|
|
||||||
InvalidEncoding(#[from] std::string::FromUtf8Error),
|
|
||||||
#[error("Unexepcted Command Output")]
|
|
||||||
UnexepctedOutput(String),
|
|
||||||
#[error("Command Error")]
|
|
||||||
CommandError(#[from] std::io::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Sink {
|
|
||||||
pub index: u32,
|
|
||||||
pub name: String,
|
|
||||||
pub description: String,
|
|
||||||
pub default: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve Default Sink
|
|
||||||
pub fn get_default_sink() -> Result<String, PulseError> {
|
|
||||||
let output = Command::new(PACTL).arg("get-default-sink").output()?;
|
|
||||||
if !output.status.success() {
|
|
||||||
return Err(PulseError::InvalidStatus(output.status));
|
|
||||||
}
|
|
||||||
Ok(String::from_utf8(output.stdout)?.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set Default PACTL Sink
|
|
||||||
pub fn set_default_sink(name: &str) -> Result<(), PulseError> {
|
|
||||||
let status = Command::new(PACTL)
|
|
||||||
.args(["set-default-sink", name])
|
|
||||||
.status()?;
|
|
||||||
if !status.success() {
|
|
||||||
return Err(PulseError::InvalidStatus(status));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve PulseAudio Sinks From PACTL
|
|
||||||
pub fn get_sinks() -> Result<Vec<Sink>, PulseError> {
|
|
||||||
// retrieve default-sink
|
|
||||||
let default = get_default_sink()?;
|
|
||||||
// spawn command and begin reading
|
|
||||||
let mut command = Command::new(PACTL)
|
|
||||||
.args(["list", "sinks"])
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.spawn()?;
|
|
||||||
let stdout = command.stdout.as_mut().ok_or(PulseError::InvalidStdout)?;
|
|
||||||
// collect output into only important lines
|
|
||||||
let mut lines = vec![];
|
|
||||||
for line in BufReader::new(stdout).lines().filter_map(|l| l.ok()) {
|
|
||||||
let line = line.trim_start();
|
|
||||||
if line.starts_with("Sink ")
|
|
||||||
|| line.starts_with("Name: ")
|
|
||||||
|| line.starts_with("Description: ")
|
|
||||||
{
|
|
||||||
lines.push(line.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ensure status after command completion
|
|
||||||
let status = command.wait()?;
|
|
||||||
if !status.success() {
|
|
||||||
return Err(PulseError::InvalidStatus(status));
|
|
||||||
}
|
|
||||||
// ensure number of lines matches expected
|
|
||||||
if lines.len() == 0 || lines.len() % 3 != 0 {
|
|
||||||
return Err(PulseError::UnexepctedOutput(lines.join("\n")));
|
|
||||||
}
|
|
||||||
// parse details into chunks and generate sinks
|
|
||||||
let mut sinks = vec![];
|
|
||||||
for chunk in lines.chunks(3) {
|
|
||||||
let (_, idx) = chunk[0]
|
|
||||||
.split_once("#")
|
|
||||||
.ok_or_else(|| PulseError::UnexepctedOutput(chunk[0].to_owned()))?;
|
|
||||||
let (_, name) = chunk[1]
|
|
||||||
.split_once(" ")
|
|
||||||
.ok_or_else(|| PulseError::UnexepctedOutput(chunk[1].to_owned()))?;
|
|
||||||
let (_, desc) = chunk[2]
|
|
||||||
.split_once(" ")
|
|
||||||
.ok_or_else(|| PulseError::UnexepctedOutput(chunk[2].to_owned()))?;
|
|
||||||
sinks.push(Sink {
|
|
||||||
index: idx.parse().unwrap(),
|
|
||||||
name: name.to_owned(),
|
|
||||||
description: desc.to_owned(),
|
|
||||||
default: name == default,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Ok(sinks)
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "powermenu"
|
|
||||||
version = "0.0.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = { version = "4.3.21", features = ["derive"] }
|
|
||||||
rmenu-plugin = { version = "0.0.1", path = "../rmenu-plugin" }
|
|
||||||
serde_json = "1.0.105"
|
|
||||||
tempfile = "3.7.1"
|
|
@ -1,107 +0,0 @@
|
|||||||
///! Functions to Build PowerMenu Actions
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::env;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::process;
|
|
||||||
|
|
||||||
use rmenu_plugin::{Action, Entry};
|
|
||||||
use tempfile::NamedTempFile;
|
|
||||||
|
|
||||||
use crate::Command;
|
|
||||||
|
|
||||||
//TODO: dynamically determine actions based on OS/Desktop/etc...
|
|
||||||
|
|
||||||
/// Ordered Map of Configured Actions
|
|
||||||
pub type Actions = BTreeMap<Command, Entry>;
|
|
||||||
|
|
||||||
/// Generate Confirmation for Specific Command
|
|
||||||
fn build_confirm(command: Command, actions: &Actions) -> Vec<Entry> {
|
|
||||||
let entry = actions.get(&command).expect("Invalid Command");
|
|
||||||
let cancel = format!("echo '{command} Cancelled'");
|
|
||||||
vec![
|
|
||||||
Entry {
|
|
||||||
name: "Cancel".to_owned(),
|
|
||||||
actions: vec![Action::new(&cancel)],
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some("".to_owned()),
|
|
||||||
},
|
|
||||||
Entry {
|
|
||||||
name: "Confirm".to_owned(),
|
|
||||||
actions: entry.actions.to_owned(),
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some("".to_owned()),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate Confirm Actions and Run Rmenu
|
|
||||||
pub fn confirm(command: Command, actions: &Actions) {
|
|
||||||
let rmenu = env::var("RMENU").unwrap_or_else(|_| "rmenu".to_owned());
|
|
||||||
let entries = build_confirm(command, actions);
|
|
||||||
// write to temporary file
|
|
||||||
let mut f = NamedTempFile::new().expect("Failed to Open Temporary File");
|
|
||||||
for entry in entries {
|
|
||||||
let json = serde_json::to_string(&entry).expect("Failed Serde Serialize");
|
|
||||||
write!(f, "{json}\n").expect("Failed Write");
|
|
||||||
}
|
|
||||||
// run command to read from temporary file
|
|
||||||
let path = f.path().to_str().expect("Invalid Temporary File Path");
|
|
||||||
let mut command = process::Command::new(rmenu)
|
|
||||||
.args(["-i", path])
|
|
||||||
.spawn()
|
|
||||||
.expect("Command Spawn Failed");
|
|
||||||
let status = command.wait().expect("Command Wait Failed");
|
|
||||||
if !status.success() {
|
|
||||||
panic!("Command Failed: {status:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate and Generate PowerMenu Actions
|
|
||||||
pub fn list_actions() -> Actions {
|
|
||||||
let mut actions = BTreeMap::new();
|
|
||||||
actions.extend(vec![
|
|
||||||
(
|
|
||||||
Command::Shutdown,
|
|
||||||
Entry {
|
|
||||||
name: "Shut Down".to_owned(),
|
|
||||||
actions: vec![Action::new("systemctl poweroff")],
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some("⏻".to_owned()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Command::Reboot,
|
|
||||||
Entry {
|
|
||||||
name: "Reboot".to_owned(),
|
|
||||||
actions: vec![Action::new("systemctl reboot")],
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some(" ".to_owned()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Command::Suspend,
|
|
||||||
Entry {
|
|
||||||
name: "Suspend".to_owned(),
|
|
||||||
actions: vec![Action::new("systemctl suspend")],
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some("⏾".to_owned()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Command::Logout,
|
|
||||||
Entry {
|
|
||||||
name: "Log Out".to_owned(),
|
|
||||||
actions: vec![Action::new("sway exit")],
|
|
||||||
comment: None,
|
|
||||||
icon: None,
|
|
||||||
icon_alt: Some("".to_owned()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
actions
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
mod action;
|
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
use rmenu_plugin::{self_exe, Method};
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Subcommand)]
|
|
||||||
pub enum Command {
|
|
||||||
ListActions { no_confirm: bool },
|
|
||||||
Shutdown,
|
|
||||||
Reboot,
|
|
||||||
Suspend,
|
|
||||||
Logout,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Command {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Command::ListActions { .. } => write!(f, "list-actions"),
|
|
||||||
Command::Shutdown => write!(f, "shutdown"),
|
|
||||||
Command::Reboot => write!(f, "reboot"),
|
|
||||||
Command::Suspend => write!(f, "suspend"),
|
|
||||||
Command::Logout => write!(f, "logout"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
|
||||||
struct Cli {
|
|
||||||
#[clap(subcommand)]
|
|
||||||
command: Option<Command>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let cli = Cli::parse();
|
|
||||||
let exe = self_exe();
|
|
||||||
|
|
||||||
let actions = action::list_actions();
|
|
||||||
let command = cli
|
|
||||||
.command
|
|
||||||
.unwrap_or(Command::ListActions { no_confirm: false });
|
|
||||||
match command {
|
|
||||||
Command::ListActions { no_confirm } => {
|
|
||||||
for (command, mut entry) in actions {
|
|
||||||
if !no_confirm {
|
|
||||||
let exec = format!("{exe} {command}");
|
|
||||||
entry.actions[0].exec = Method::Run(exec);
|
|
||||||
}
|
|
||||||
println!("{}", serde_json::to_string(&entry).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
command => {
|
|
||||||
action::confirm(command, &actions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -125,7 +125,7 @@ struct OptionArgs {
|
|||||||
pub theme: Option<String>,
|
pub theme: Option<String>,
|
||||||
// search settings
|
// search settings
|
||||||
/// Override Default Placeholder
|
/// Override Default Placeholder
|
||||||
#[arg(short, long)]
|
#[arg(short = 'P', long)]
|
||||||
pub placeholder: Option<String>,
|
pub placeholder: Option<String>,
|
||||||
/// Override Search Restriction
|
/// Override Search Restriction
|
||||||
#[arg(short = 'r', long)]
|
#[arg(short = 'r', long)]
|
||||||
|
@ -25,10 +25,6 @@ plugins:
|
|||||||
drun:
|
drun:
|
||||||
exec: ["~/.config/rmenu/rmenu-desktop"]
|
exec: ["~/.config/rmenu/rmenu-desktop"]
|
||||||
cache: onlogin
|
cache: onlogin
|
||||||
audio:
|
|
||||||
exec: ["~/.config/rmenu/rmenu-audio"]
|
|
||||||
cache: false
|
|
||||||
placeholder: "Select an Audio Sink"
|
|
||||||
network:
|
network:
|
||||||
exec: ["~/.config/rmenu/rmenu-network"]
|
exec: ["~/.config/rmenu/rmenu-network"]
|
||||||
cache: false
|
cache: false
|
||||||
@ -37,6 +33,13 @@ plugins:
|
|||||||
exec: ["~/.config/rmenu/rmenu-window"]
|
exec: ["~/.config/rmenu/rmenu-window"]
|
||||||
cache: false
|
cache: false
|
||||||
placeholder: "Jump to the Specified Window"
|
placeholder: "Jump to the Specified Window"
|
||||||
|
audio:
|
||||||
|
exec: ["sh", "~/.config/rmenu/pactl-audio.sh"]
|
||||||
|
cache: false
|
||||||
|
placeholder: "Select an Audio Sink"
|
||||||
|
powermenu:
|
||||||
|
exec: ["sh", "~/.config/rmenu/powermenu.sh", "list", "confirm"]
|
||||||
|
cache: false
|
||||||
|
|
||||||
# custom keybindings
|
# custom keybindings
|
||||||
keybinds:
|
keybinds:
|
||||||
|
Loading…
Reference in New Issue
Block a user