init
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
*
|
||||
* Author : Aditya Shakya (adi1090x)
|
||||
* Github : @adi1090x
|
||||
*
|
||||
* Rofi Theme File
|
||||
* Rofi Version: 1.7.3
|
||||
**/
|
||||
|
||||
/*****----- Configuration -----*****/
|
||||
configuration {
|
||||
modi: "";
|
||||
show-icons: false;
|
||||
drun-display-format: "{name}";
|
||||
window-format: "{w} · {c} · {t}";
|
||||
}
|
||||
|
||||
/*****----- Global Properties -----*****/
|
||||
@import "../colors.rasi"
|
||||
@import "../fonts.rasi"
|
||||
|
||||
* {
|
||||
border-colour: var(border);
|
||||
handle-colour: var(selected);
|
||||
background-colour: var(background);
|
||||
foreground-colour: var(foreground);
|
||||
alternate-background: var(background-alt);
|
||||
normal-background: var(background);
|
||||
normal-foreground: var(foreground);
|
||||
urgent-background: var(urgent);
|
||||
urgent-foreground: var(background);
|
||||
active-background: var(active);
|
||||
active-foreground: var(background);
|
||||
selected-normal-background: var(selected);
|
||||
selected-normal-foreground: var(background);
|
||||
selected-urgent-background: var(active);
|
||||
selected-urgent-foreground: var(background);
|
||||
selected-active-background: var(urgent);
|
||||
selected-active-foreground: var(background);
|
||||
alternate-normal-background: var(background);
|
||||
alternate-normal-foreground: var(foreground);
|
||||
alternate-urgent-background: var(urgent);
|
||||
alternate-urgent-foreground: var(background);
|
||||
alternate-active-background: var(active);
|
||||
alternate-active-foreground: var(background);
|
||||
}
|
||||
|
||||
/*****----- Main Window -----*****/
|
||||
window {
|
||||
/* properties for window widget */
|
||||
transparency: "real";
|
||||
location: center;
|
||||
anchor: center;
|
||||
fullscreen: false;
|
||||
width: 600px;
|
||||
x-offset: 0px;
|
||||
y-offset: 0px;
|
||||
|
||||
/* properties for all widgets */
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 1px solid;
|
||||
border-radius: 10px;
|
||||
border-color: @border-colour;
|
||||
cursor: "default";
|
||||
/* Backgroud Colors */
|
||||
background-color: @background-colour;
|
||||
/* Backgroud Image */
|
||||
//background-image: url("/path/to/image.png", none);
|
||||
/* Simple Linear Gradient */
|
||||
//background-image: linear-gradient(red, orange, pink, purple);
|
||||
/* Directional Linear Gradient */
|
||||
//background-image: linear-gradient(to bottom, pink, yellow, magenta);
|
||||
/* Angle Linear Gradient */
|
||||
//background-image: linear-gradient(45, cyan, purple, indigo);
|
||||
}
|
||||
|
||||
/*****----- Main Box -----*****/
|
||||
mainbox {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 30px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px 0px 0px 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
children: [ "message", "listview", "inputbar" ];
|
||||
}
|
||||
|
||||
/*****----- Inputbar -----*****/
|
||||
inputbar {
|
||||
enabled: false;
|
||||
spacing: 10px;
|
||||
margin: 0;
|
||||
padding: 20px 0px 0;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
children: [ "textbox-prompt-colon", "entry", "mode-switcher" ];
|
||||
}
|
||||
|
||||
prompt {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
textbox-prompt-colon {
|
||||
enabled: true;
|
||||
padding: 5px 0px 0px 15px;
|
||||
expand: false;
|
||||
font: "MonarchOS 14";
|
||||
str: "";
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
entry {
|
||||
enabled: true;
|
||||
padding: 5px 0px;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
cursor: text;
|
||||
placeholder: "...";
|
||||
placeholder-color: inherit;
|
||||
}
|
||||
num-filtered-rows {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
textbox-num-sep {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
str: "/";
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
num-rows {
|
||||
enabled: true;
|
||||
expand: false;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
case-indicator {
|
||||
enabled: true;
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
|
||||
/*****----- Listview -----*****/
|
||||
listview {
|
||||
enabled: true;
|
||||
columns: 1;
|
||||
lines: 8;
|
||||
cycle: true;
|
||||
dynamic: true;
|
||||
scrollbar: false;
|
||||
layout: vertical;
|
||||
reverse: false;
|
||||
fixed-height: true;
|
||||
fixed-columns: true;
|
||||
|
||||
spacing: 5px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: "default";
|
||||
}
|
||||
scrollbar {
|
||||
handle-width: 5px;
|
||||
handle-color: @handle-colour;
|
||||
border-radius: 10px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/*****----- Elements -----*****/
|
||||
element {
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 5px 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 10px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
cursor: pointer;
|
||||
}
|
||||
element normal.normal {
|
||||
background-color: transparent;
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
element normal.urgent {
|
||||
background-color: var(urgent-background);
|
||||
text-color: var(urgent-foreground);
|
||||
}
|
||||
element normal.active {
|
||||
background-color: var(normal-foreground);
|
||||
text-color: var(normal-background);
|
||||
}
|
||||
element selected.normal {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(normal-foreground);
|
||||
}
|
||||
element selected.urgent {
|
||||
background-color: var(selected-urgent-background);
|
||||
text-color: var(normal-background);
|
||||
}
|
||||
element selected.active {
|
||||
background-color: var(selected-active-background);
|
||||
text-color: var(normal-background);
|
||||
}
|
||||
|
||||
element-icon {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
size: 24px;
|
||||
cursor: inherit;
|
||||
}
|
||||
element-text {
|
||||
background-color: transparent;
|
||||
text-color: inherit;
|
||||
highlight: inherit;
|
||||
cursor: inherit;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
}
|
||||
|
||||
/*****----- Mode Switcher -----*****/
|
||||
mode-switcher{
|
||||
enabled: true;
|
||||
spacing: 10px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
button {
|
||||
padding: 7px 15px 7px 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 100%;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
button selected {
|
||||
background-color: var(selected-normal-background);
|
||||
text-color: var(selected-normal-foreground);
|
||||
}
|
||||
|
||||
/*****----- Message -----*****/
|
||||
message {
|
||||
enabled: true;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px solid;
|
||||
border-radius: 0px 0px 0px 0px;
|
||||
border-color: @border-colour;
|
||||
background-color: transparent;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
textbox {
|
||||
padding: 8px 10px;
|
||||
border: 0px solid;
|
||||
border-radius: 10px;
|
||||
border-color: @border-colour;
|
||||
background-color: @alternate-background;
|
||||
text-color: @foreground-colour;
|
||||
vertical-align: 0.5;
|
||||
horizontal-align: 0.0;
|
||||
highlight: none;
|
||||
placeholder-color: @foreground-colour;
|
||||
blink: true;
|
||||
markup: true;
|
||||
}
|
||||
error-message {
|
||||
padding: 10px;
|
||||
border: 2px solid;
|
||||
border-radius: 10px;
|
||||
border-color: @border-colour;
|
||||
background-color: @background-colour;
|
||||
text-color: @foreground-colour;
|
||||
}
|
||||
Executable
+317
@@ -0,0 +1,317 @@
|
||||
#!/usr/bin/env bash
|
||||
# __ _ _ _ _ _ _
|
||||
# _ __ ___ / _(_) | |__ | |_ _ ___| |_ ___ ___ | |_| |__
|
||||
# | '__/ _ \| |_| |_____| '_ \| | | | |/ _ \ __/ _ \ / _ \| __| '_ \
|
||||
# | | | (_) | _| |_____| |_) | | |_| | __/ || (_) | (_) | |_| | | |
|
||||
# |_| \___/|_| |_| |_.__/|_|\__,_|\___|\__\___/ \___/ \__|_| |_|
|
||||
#
|
||||
# Author: Nick Clyde (clydedroid)
|
||||
#
|
||||
# A script that generates a rofi menu that uses bluetoothctl to
|
||||
# connect to bluetooth devices and display status info.
|
||||
#
|
||||
# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu)
|
||||
# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl)
|
||||
#
|
||||
# Depends on:
|
||||
# Arch repositories: rofi, bluez-utils (contains bluetoothctl)
|
||||
|
||||
# Constants
|
||||
divider="---------"
|
||||
goback="Back"
|
||||
|
||||
# Checks if bluetooth controller is powered on
|
||||
power_on() {
|
||||
if bluetoothctl show | grep -q "Powered: yes"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles power state
|
||||
toggle_power() {
|
||||
if power_on; then
|
||||
bluetoothctl power off
|
||||
show_menu
|
||||
else
|
||||
if rfkill list bluetooth | grep -q 'blocked: yes'; then
|
||||
rfkill unblock bluetooth && sleep 3
|
||||
fi
|
||||
bluetoothctl power on
|
||||
show_menu
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if controller is scanning for new devices
|
||||
scan_on() {
|
||||
if bluetoothctl show | grep -q "Discovering: yes"; then
|
||||
echo "Scan: on"
|
||||
return 0
|
||||
else
|
||||
echo "Scan: off"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles scanning state
|
||||
toggle_scan() {
|
||||
if scan_on; then
|
||||
kill $(pgrep -f "bluetoothctl scan on")
|
||||
bluetoothctl scan off
|
||||
show_menu
|
||||
else
|
||||
bluetoothctl scan on &
|
||||
echo "Scanning..."
|
||||
sleep 5
|
||||
show_menu
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if controller is able to pair to devices
|
||||
pairable_on() {
|
||||
if bluetoothctl show | grep -q "Pairable: yes"; then
|
||||
echo "Pairable: on"
|
||||
return 0
|
||||
else
|
||||
echo "Pairable: off"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles pairable state
|
||||
toggle_pairable() {
|
||||
if pairable_on; then
|
||||
bluetoothctl pairable off
|
||||
show_menu
|
||||
else
|
||||
bluetoothctl pairable on
|
||||
show_menu
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if controller is discoverable by other devices
|
||||
discoverable_on() {
|
||||
if bluetoothctl show | grep -q "Discoverable: yes"; then
|
||||
echo "Discoverable: on"
|
||||
return 0
|
||||
else
|
||||
echo "Discoverable: off"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles discoverable state
|
||||
toggle_discoverable() {
|
||||
if discoverable_on; then
|
||||
bluetoothctl discoverable off
|
||||
show_menu
|
||||
else
|
||||
bluetoothctl discoverable on
|
||||
show_menu
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if a device is connected
|
||||
device_connected() {
|
||||
device_info=$(bluetoothctl info "$1")
|
||||
if echo "$device_info" | grep -q "Connected: yes"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles device connection
|
||||
toggle_connection() {
|
||||
if device_connected "$1"; then
|
||||
bluetoothctl disconnect "$1"
|
||||
device_menu "$device"
|
||||
else
|
||||
bluetoothctl connect "$1"
|
||||
device_menu "$device"
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if a device is paired
|
||||
device_paired() {
|
||||
device_info=$(bluetoothctl info "$1")
|
||||
if echo "$device_info" | grep -q "Paired: yes"; then
|
||||
echo "Paired: yes"
|
||||
return 0
|
||||
else
|
||||
echo "Paired: no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles device paired state
|
||||
toggle_paired() {
|
||||
if device_paired "$1"; then
|
||||
bluetoothctl remove "$1"
|
||||
device_menu "$device"
|
||||
else
|
||||
bluetoothctl pair "$1"
|
||||
device_menu "$device"
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if a device is trusted
|
||||
device_trusted() {
|
||||
device_info=$(bluetoothctl info "$1")
|
||||
if echo "$device_info" | grep -q "Trusted: yes"; then
|
||||
echo "Trusted: yes"
|
||||
return 0
|
||||
else
|
||||
echo "Trusted: no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Toggles device connection
|
||||
toggle_trust() {
|
||||
if device_trusted "$1"; then
|
||||
bluetoothctl untrust "$1"
|
||||
device_menu "$device"
|
||||
else
|
||||
bluetoothctl trust "$1"
|
||||
device_menu "$device"
|
||||
fi
|
||||
}
|
||||
|
||||
# Prints a short string with the current bluetooth status
|
||||
# Useful for status bars like polybar, etc.
|
||||
print_status() {
|
||||
if power_on; then
|
||||
printf ''
|
||||
|
||||
paired_devices_cmd="devices Paired"
|
||||
# Check if an outdated version of bluetoothctl is used to preserve backwards compatibility
|
||||
if (( $(echo "$(bluetoothctl version | cut -d ' ' -f 2) < 5.65" | bc -l) )); then
|
||||
paired_devices_cmd="paired-devices"
|
||||
fi
|
||||
|
||||
mapfile -t paired_devices < <(bluetoothctl $paired_devices_cmd | grep Device | cut -d ' ' -f 2)
|
||||
counter=0
|
||||
|
||||
for device in "${paired_devices[@]}"; do
|
||||
if device_connected "$device"; then
|
||||
device_alias=$(bluetoothctl info "$device" | grep "Alias" | cut -d ' ' -f 2-)
|
||||
|
||||
if [ $counter -gt 0 ]; then
|
||||
printf ", %s" "$device_alias"
|
||||
else
|
||||
printf " %s" "$device_alias"
|
||||
fi
|
||||
|
||||
((counter++))
|
||||
fi
|
||||
done
|
||||
printf "\n"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# A submenu for a specific device that allows connecting, pairing, and trusting
|
||||
device_menu() {
|
||||
device=$1
|
||||
|
||||
# Get device name and mac address
|
||||
device_name=$(echo "$device" | cut -d ' ' -f 3-)
|
||||
mac=$(echo "$device" | cut -d ' ' -f 2)
|
||||
|
||||
# Build options
|
||||
if device_connected "$mac"; then
|
||||
connected="Connected: yes"
|
||||
else
|
||||
connected="Connected: no"
|
||||
fi
|
||||
paired=$(device_paired "$mac")
|
||||
trusted=$(device_trusted "$mac")
|
||||
options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit"
|
||||
|
||||
# Open rofi menu, read chosen option
|
||||
chosen="$(echo -e "$options" | $rofi_command "$device_name")"
|
||||
|
||||
# Match chosen option to command
|
||||
case "$chosen" in
|
||||
"" | "$divider")
|
||||
echo "No option chosen."
|
||||
;;
|
||||
"$connected")
|
||||
toggle_connection "$mac"
|
||||
;;
|
||||
"$paired")
|
||||
toggle_paired "$mac"
|
||||
;;
|
||||
"$trusted")
|
||||
toggle_trust "$mac"
|
||||
;;
|
||||
"$goback")
|
||||
show_menu
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Opens a rofi menu with current bluetooth status and options to connect
|
||||
show_menu() {
|
||||
# Get menu options
|
||||
if power_on; then
|
||||
power="Power: on"
|
||||
|
||||
# Human-readable names of devices, one per line
|
||||
# If scan is off, will only list paired devices
|
||||
devices=$(bluetoothctl devices | grep Device | cut -d ' ' -f 3-)
|
||||
|
||||
# Get controller flags
|
||||
scan=$(scan_on)
|
||||
pairable=$(pairable_on)
|
||||
discoverable=$(discoverable_on)
|
||||
|
||||
# Options passed to rofi
|
||||
options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit"
|
||||
else
|
||||
power="Power: off"
|
||||
options="$power\nExit"
|
||||
fi
|
||||
|
||||
# Open rofi menu, read chosen option
|
||||
chosen="$(echo -e "$options" | $rofi_command "Bluetooth")"
|
||||
|
||||
# Match chosen option to command
|
||||
case "$chosen" in
|
||||
"" | "$divider")
|
||||
echo "No option chosen."
|
||||
;;
|
||||
"$power")
|
||||
toggle_power
|
||||
;;
|
||||
"$scan")
|
||||
toggle_scan
|
||||
;;
|
||||
"$discoverable")
|
||||
toggle_discoverable
|
||||
;;
|
||||
"$pairable")
|
||||
toggle_pairable
|
||||
;;
|
||||
*)
|
||||
device=$(bluetoothctl devices | grep "$chosen")
|
||||
# Open a submenu if a device is selected
|
||||
if [[ $device ]]; then device_menu "$device"; fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Rofi command to pipe into, can add any options here
|
||||
rofi_command="rofi -dmenu $* -p -theme $HOME/.config/rofi/bluetooth/bluetooth.rasi -mesg -Bluetooth-Control"
|
||||
|
||||
case "$1" in
|
||||
--status)
|
||||
print_status
|
||||
;;
|
||||
*)
|
||||
show_menu
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user