aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rwxr-xr-xutils/backlight_default.sh32
-rwxr-xr-xutils/colors.sh78
-rwxr-xr-xutils/cryptocheck31
-rwxr-xr-xutils/cryptonotify19
-rwxr-xr-xutils/disable_meta_key_guest.sh94
-rwxr-xr-xutils/heads-up-display88
-rwxr-xr-xutils/hex2rgb.sh3
-rwxr-xr-xutils/kill-notify4
-rwxr-xr-xutils/kill-process6
-rwxr-xr-xutils/mnt27
-rwxr-xr-xutils/move_terminal65
-rwxr-xr-xutils/neovim.sh422
-rwxr-xr-xutils/pack88
-rwxr-xr-xutils/rofi-network-manager.sh252
-rwxr-xr-xutils/root.sh152
-rwxr-xr-xutils/run_with_display.sh19
-rwxr-xr-xutils/scratchpad147
-rwxr-xr-xutils/screenshot102
-rwxr-xr-xutils/sendkeys.awk86
-rwxr-xr-xutils/sext47
-rwxr-xr-xutils/track-books.sh19
-rwxr-xr-xutils/umnt22
-rwxr-xr-xutils/waypipe_app16
-rwxr-xr-xutils/wayvnc_session10
-rwxr-xr-xutils/window_manager_name.sh29
-rwxr-xr-xutils/xtouch38
26 files changed, 1896 insertions, 0 deletions
diff --git a/utils/backlight_default.sh b/utils/backlight_default.sh
new file mode 100755
index 0000000..b79e680
--- /dev/null
+++ b/utils/backlight_default.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+set -e
+
+backlight_sys_dir="/sys/class/backlight/intel_backlight"
+
+read -r max_brightness < "${backlight_sys_dir}/max_brightness"
+read -r curr_brightness < "${backlight_sys_dir}/brightness"
+
+if ! groups | grep -q backlight; then
+ echo "User is not in the backlight group"
+ exit 1
+fi
+
+if [ "$#" -eq 0 ] ; then
+ # set to half that of 'max_brightness'
+ echo $((max_brightness / 2)) > "$backlight_sys_dir"/brightness
+ exit 0
+fi
+
+case "$1" in
+ up) increment="+ 10" ;;
+ down) increment="- 10" ;;
+ *) exit 1 ;;
+esac
+
+new_brightness=$(($curr_brightness $increment))
+
+if $((new_brightness < 1)) || $((new_brightness > $max_brightness)); then
+ exit 1
+else
+ echo "$new_brightness" > "$backlight_sys_dir"/brightness
+fi
diff --git a/utils/colors.sh b/utils/colors.sh
new file mode 100755
index 0000000..fc1c10c
--- /dev/null
+++ b/utils/colors.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+colors=$@
+for (( n=0; n < $colors; n++ )) do
+ printf " [%d] $(tput setaf $n)%s$(tput sgr0)" $n "Hello World!
+"
+done
+PADDING='Padding'
+
+main() {
+ local xterm_start=0 \
+ xterm_width=8 \
+ xterm_height=2
+
+ local cube_start=$((xterm_start + xterm_width * xterm_height)) \
+ cube_width=6 \
+ cube_height=$((6 * 6))
+
+ local greys_start=$((cube_start + cube_width * cube_height)) \
+ greys_width=8 \
+ greys_height=3
+
+ color_block $xterm_start $xterm_width $xterm_height
+ color_block $cube_start $cube_width $cube_height use_padding
+ color_block $greys_start $greys_width $greys_height
+ echo
+}
+
+color_block() {
+ local start=$1 width=$2 height=$3 use_padding=$4
+ local max s color_nums colors
+
+ max=$((start + width * height - 1))
+
+ echo
+ for s in $(seq $start $width $max); do
+ color_nums=$(seq $s $((s + width - 1)))
+ colors="${use_padding:+$PADDING }${color_nums}${use_padding:+ $PADDING}"
+
+ printf '%s%s %s%s\n' \
+ "$(fg_bars $colors)" $ansi_reset \
+ "$(bg_bars $colors)" $ansi_reset
+ done
+}
+
+fg_bars() {
+ for color in $@; do
+ color_bar ansi_fg $color ''
+ done
+}
+
+bg_bars() {
+ for color in $@; do
+ color_bar ansi_bg $color ' '
+ done
+}
+
+color_bar() {
+ local ansi=$1 color=$2 trail=$3
+
+ if [ "$color" == $PADDING ]; then
+ printf '%s %s' $ansi_reset "$trail"
+ else
+ local color_seq=$($ansi $color)
+ printf '%s %03d%s' $color_seq $color "$trail"
+ fi
+}
+
+ansi_reset=$'\033[0m'
+
+ansi_fg() {
+ printf '\033[38;5;%dm' $1
+}
+
+ansi_bg() {
+ printf '\033[48;5;%dm' $1
+}
+
+main
diff --git a/utils/cryptocheck b/utils/cryptocheck
new file mode 100755
index 0000000..02ba42d
--- /dev/null
+++ b/utils/cryptocheck
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+if [ ! -d ~/.cache/crypto ]; then
+ mkdir ~/.cache/crypto
+fi
+ticker=(BTC ETH ADA DOT SOL XMR)
+
+for currency in "${ticker[@]}"; do
+ echo "$currency"
+done | while read coin
+ do
+ price=$(curl rate.sx/1$coin)
+ if [ $coin = "BTC" ]; then
+ icon=󰠓
+ elif [ $coin = "ETH" ]; then
+ icon=󰡪
+ elif [ $coin = "ADA" ]; then
+ icon=󰝨
+ elif [ $coin = "DOT" ]; then
+ icon=󰐇
+ elif [ $coin = "SOL" ]; then
+ icon=󰘙
+ elif [ $coin = "XMR" ]; then
+ icon=󰝴
+ fi
+
+ echo "$icon $coin: $price" > ~/.cache/crypto/$coin
+
+ done
+
+date > ~/.cache/crypto/time
+
diff --git a/utils/cryptonotify b/utils/cryptonotify
new file mode 100755
index 0000000..47883c3
--- /dev/null
+++ b/utils/cryptonotify
@@ -0,0 +1,19 @@
+#!/bin/sh
+source cryptocheck
+Output=
+for file in ~/.cache/crypto/*
+do
+ if [ ! -z "$Output" ]; then
+ if [ ! $(basename $file) = "time" ]; then
+ Output="$Output\n$(cat $file)"
+ fi
+ else
+ if [ ! $(basename $file) = "time" ]; then
+ Output="$Output$(cat $file)"
+ fi
+ fi
+
+done
+
+Output="$Output\n$(cat ~/.cache/crypto/time)"
+notify-send "Crypto Prices" "$Output"
diff --git a/utils/disable_meta_key_guest.sh b/utils/disable_meta_key_guest.sh
new file mode 100755
index 0000000..acbbdf5
--- /dev/null
+++ b/utils/disable_meta_key_guest.sh
@@ -0,0 +1,94 @@
+ain "$@"
+#!/usr/bin/env bash
+
+# Function to find the QEMU monitor socket dynamically and extract the VM name
+get_socket_path() {
+ local socket_dir="$HOME/machines/vm" # Directory where your sockets are stored
+ local socket_file=$(find "$socket_dir" -type s -name "*-monitor.socket" | head -n 1)
+
+ echo "[DEBUG] Found socket file: $socket_file" # Debugging line to check the socket file
+
+ if [[ -z "$socket_file" ]]; then
+ echo "Error: No QEMU monitor socket found in $socket_dir." >&2
+ exit 1
+ fi
+
+ # Extract the VM name from the socket file name
+ local vm_name=$(basename "$socket_file" -monitor.socket)
+ echo "[DEBUG] VM name detected: $vm_name" # Debugging line to check VM name
+
+ echo "$socket_file" # Return the full socket path
+ echo "$vm_name" # Return the VM name
+}
+
+# Function to check if sendkeys.awk is in the user's PATH or fall back to specific directories
+find_sendkeys_awk() {
+ # Check if sendkeys.awk is in the user's PATH
+ if command -v sendkeys.awk &>/dev/null; then
+ echo "$(command -v sendkeys.awk)"
+ return 0
+ fi
+
+ # Otherwise, check in specific fallback directories
+ local possible_paths=(
+ "$HOME/.scripts/env/linux/utils/sendkeys.awk"
+ "$HOME/.scripts/sendkeys.awk"
+ )
+
+ for path in "${possible_paths[@]}"; do
+ if [[ -f "$path" ]]; then
+ echo "$path"
+ return 0
+ fi
+ done
+
+ echo "sendkeys.awk not found in the user's PATH or known directories." >&2
+ exit 1
+}
+
+send_guest_command() {
+ local cmd="$1"
+ local socket="$2"
+ echo "$cmd" | awk -f "$SENDKEYS_AWK" | socat - UNIX-CONNECT:"$socket"
+}
+
+main() {
+ # Get the QEMU socket and VM name dynamically
+ SOCKET=$(get_socket_path)
+ VM_NAME=$(basename "$SOCKET" -monitor.socket)
+
+ # Debugging output to verify the socket and VM name
+ echo "[DEBUG] Using socket: $SOCKET"
+ echo "[DEBUG] VM name: $VM_NAME"
+
+ # If no socket file is found, exit
+ if [[ ! -S "$SOCKET" ]]; then
+ echo "Error: QEMU monitor socket for $VM_NAME does not exist or is not available."
+ exit 1
+ fi
+
+ # Try to find the sendkeys.awk file
+ SENDKEYS_AWK=$(find_sendkeys_awk)
+
+ echo "[*] Attempting Caps Lock to Super remapping on all known platforms..."
+
+ # === X11 ===
+ send_guest_command "setxkbmap -option caps:super" "$SOCKET"
+ send_guest_command "xmodmap -e 'remove Mod4 = Super_L Super_R'" "$SOCKET"
+ send_guest_command "xmodmap -e 'keycode 133 = NoSymbol'" "$SOCKET"
+ send_guest_command "xmodmap -e 'keycode 134 = NoSymbol'" "$SOCKET"
+
+ # === Wayland (note: this just gives a reminder) ===
+ send_guest_command "gsettings set org.gnome.desktop.input-sources xkb-options \"['caps:super']\"" "$SOCKET"
+ send_guest_command "echo 'Wayland? Try remapping via wlroots/wlr-keyboard'" "$SOCKET"
+
+ # === Windows (registry scancode map) ===
+ send_guest_command "powershell -Command \"Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout' -Name 'Scancode Map' -Value ([byte[]](0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x3A,0x00,0x5B,0x00,0x00,0x00))\"" "$SOCKET"
+
+ # === macOS (hidutil remap) ===
+ send_guest_command "hidutil property --set '{\"UserKeyMapping\":[{\"HIDKeyboardModifierMappingSrc\":0x700000039,\"HIDKeyboardModifierMappingDst\":0x7000000E3}]}'" "$SOCKET"
+
+ echo "[*] Done sending remapping commands to guest."
+}
+
+main "$@"
diff --git a/utils/heads-up-display b/utils/heads-up-display
new file mode 100755
index 0000000..54f5de1
--- /dev/null
+++ b/utils/heads-up-display
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+# Created By: srdusr
+# Created On: Wed 05 Feb 2023 01:24:37 AM CAT
+# Project: bspwm scratchpad (Heads-Up-Display) with tmux session
+
+### Alternative method
+
+#if id="$(xdo id -N heads-up-display)"; then
+# bspc node "$id" -g hidden -f
+#else
+# #kitty --class "heads-up-display" -e tmux new-session -A -s HUD -e bash >/dev/null 2>&1 &
+# wezterm start --class "heads-up-display" -e tmux new-session -A -s HUD -e bash >/dev/null 2>&1 &
+#fi
+
+#- - - - - - - - - -
+
+### Alternative method
+
+#id=$(xdotool search --class heads-up-display)
+#if [ "$id" = "" ]; then
+# #kitty --class "Heads-Up-Display" -e tmux new-session -A -s HUD -e bash > /dev/null 2>&1 &
+# alacritty --class "heads-up-display" -e tmux new-session -A -s HUD -e bash >/dev/null 2>&1 &
+#else
+# if [ ! -f /tmp/hide_hud ]; then
+# touch /tmp/hide_hud && xdo hide "$id"
+# elif [ -f /tmp/hide_hud ]; then
+# rm /tmp/hide_hud && xdo show "$id"
+# fi
+#fi
+
+
+
+# Set the environment variables to x11 to allow working in Wayland
+export GDK_BACKEND=x11
+export QT_QPA_PLATFORM=xcb
+#export WAYLAND_DISPLAY=""
+export WINIT_UNIX_BACKEND=x11
+
+# Supported terminals and dropdown class
+supported_terminals=("wezterm" "kitty" "alacritty")
+
+# Check if any supported terminal with scratchpad class is running
+for term in "${supported_terminals[@]}"; do
+ if pgrep -f "$term.*--class heads-up-display" >/dev/null; then
+ my_term="$term"
+ break
+ fi
+done
+
+# If no supported terminal is running, start the first available one
+if [ "$my_term" = "" ]; then
+ for term in "${supported_terminals[@]}"; do
+ if command -v "$term" >/dev/null 2>&1; then
+ my_term="$term"
+ break
+ fi
+ done
+ if [ "$my_term" = "" ]; then
+ echo "No supported terminal found." && exit 1
+ fi
+
+ # Start terminal with scratchpad class
+ case "$my_term" in
+ "wezterm") wezterm start --class heads-up-display -e tmux new-session -A -s HUD -e bash htop & ;;
+ "kitty") kitty --class heads-up-display tmux new-session -A -s HUD -e bash htop & ;;
+ "alacritty") alacritty --class heads-up-display -e tmux new-session -A -s HUD -e bash htop & ;;
+
+ esac
+fi
+
+# Get the window ID of the scratchpad terminal
+id="$(xdo id -N heads-up-display)"
+
+# Toggle scratchpad terminal visibility
+if [ "$id" != "" ]; then
+ if xwininfo -id "$id" | grep "Map State: IsViewable" >/dev/null; then
+ # Scratchpad is visible, hide it
+ dimensions="$(xwininfo -id "$id" | awk '/Width:|Height:/ { printf("%s=%s;", tolower($1), $2) }')"
+ xdo hide "$id" 2>/dev/null
+ else
+ # Scratchpad is hidden, show it and restore dimensions
+ xdo show "$id"
+ xdotool windowsize "$id" "$(echo "$dimensions" | tr ';' ' ')" 2>/dev/null
+ xdotool windowactivate "$id"
+ xdotool windowfocus "$id"
+ fi
+fi
diff --git a/utils/hex2rgb.sh b/utils/hex2rgb.sh
new file mode 100755
index 0000000..a8ccc38
--- /dev/null
+++ b/utils/hex2rgb.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+hex="${1}"
+printf "R: %d G: %d B: %d\n" 0x"${hex:0:2}" 0x"${hex:2:2}" 0x"${hex:4:2}"
diff --git a/utils/kill-notify b/utils/kill-notify
new file mode 100755
index 0000000..f7f749e
--- /dev/null
+++ b/utils/kill-notify
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Kills an application and sends a notification that it's been killed
+
+killall "$1" && notify-send "Killed $1"
diff --git a/utils/kill-process b/utils/kill-process
new file mode 100755
index 0000000..5247e5f
--- /dev/null
+++ b/utils/kill-process
@@ -0,0 +1,6 @@
+#!/bin/sh
+# pipes list of processes into rofi/dmenu and kills the selection
+
+proc=$(ps -u $USER -o pid,%mem,%cpu,comm | sort -b -k2 -r | sed -n '1!p' | dmenu -i -p "Kill" | awk '{print $1,$4}')
+
+[ -z "$proc" ] || (kill -15 $(echo $proc | awk '{print $1}') 2>/dev/null && notify-send "$(echo $proc | awk '{print $2}') killed")
diff --git a/utils/mnt b/utils/mnt
new file mode 100755
index 0000000..dc19ca9
--- /dev/null
+++ b/utils/mnt
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# mount disk
+set -e
+. ~/etc/colors/current
+
+d() case $LABEL in
+Windows) echo "/win" ;;
+*) echo "${1:-$HOME}/dev/$NAME" ;;
+esac
+
+lsblk -Po NAME,SIZE,MOUNTPOINT,FSTYPE,LABEL | while read -r a; do
+ eval "$a"
+
+ [ "$FSTYPE" ] && [ ! "$MOUNTPOINT" ] &&
+ printf "%-4s:%s:%s:-> %s\n" \
+ "$NAME" \
+ "$SIZE" \
+ "${LABEL:-unnamed}" \
+ "$(d \~)"
+
+done | column -ts':' -o' ' | menu -p mount | {
+ read -r NAME _
+ eval "$(lsblk -Polabel "/dev/$NAME")"
+ mkdir -p "$(d)"
+ sudo mount -o "umask=000" "/dev/$NAME" "$(d)"
+ notify-send summary "<span color='#$green'>$NAME: $LABEL</span>\n$(d \~)"
+}
diff --git a/utils/move_terminal b/utils/move_terminal
new file mode 100755
index 0000000..2b447d0
--- /dev/null
+++ b/utils/move_terminal
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+SCRATCHPAD_CLASSES=("scratchpad" "pack" "heads-up-display")
+PRIMARY_MONITOR="eDP-1"
+SECOND_MONITOR="HDMI-A-2"
+
+PRIMARY_WORKSPACES=(2 4 5 6)
+SECOND_WORKSPACES=(1 3)
+
+# Check if second monitor exists
+if ! hyprctl monitors -j | jq -e ".[] | select(.name == \"$SECOND_MONITOR\")" >/dev/null; then
+ # No second monitor, do nothing
+ exit 0
+fi
+
+# Check if list of workspaces has any windows
+has_windows_in_workspaces() {
+ local workspaces=("$@")
+ for ws in "${workspaces[@]}"; do
+ local count
+ count=$(hyprctl clients -j | jq "[.[] | select(.workspace.id == $ws)] | length")
+ if ((count > 0)); then
+ return 0
+ fi
+ done
+ return 1
+}
+
+# Check window presence
+primary_has_windows=false
+second_has_windows=false
+
+if has_windows_in_workspaces "${PRIMARY_WORKSPACES[@]}"; then
+ primary_has_windows=true
+fi
+if has_windows_in_workspaces "${SECOND_WORKSPACES[@]}"; then
+ second_has_windows=true
+fi
+
+# Decide target monitor
+if [[ "$primary_has_windows" == true && "$second_has_windows" == false ]]; then
+ TARGET_MONITOR="$SECOND_MONITOR"
+elif [[ "$primary_has_windows" == false && "$second_has_windows" == true ]]; then
+ TARGET_MONITOR="$PRIMARY_MONITOR"
+else
+ TARGET_MONITOR="$SECOND_MONITOR" # both busy or both empty → second monitor
+fi
+
+# Get workspace id of the target monitor
+TARGET_WORKSPACE=$(hyprctl monitors -j | jq ".[] | select(.name == \"$TARGET_MONITOR\") | .activeWorkspace.id")
+
+# Wait for scratchpad window to appear and move it
+for _ in {1..20}; do
+ for class in "${SCRATCHPAD_CLASSES[@]}"; do
+ client=$(hyprctl clients -j | jq -r ".[] | select(.class == \"$class\") | .address")
+ if [[ -n "$client" ]]; then
+ hyprctl dispatch movetoworkspacesilent "$TARGET_WORKSPACE,address:$client"
+ hyprctl dispatch focuswindow address:"$client"
+ exit 0
+ fi
+ done
+ sleep 0.1
+done
+
+exit 1
diff --git a/utils/neovim.sh b/utils/neovim.sh
new file mode 100755
index 0000000..c9adcca
--- /dev/null
+++ b/utils/neovim.sh
@@ -0,0 +1,422 @@
+#!/bin/bash
+
+# Created By: srdusr
+# Created On: Sat 12 Aug 2023 13:11:39 CAT
+# Project: Install/update/uninstall/change version Neovim script, primarily for Linux but may work in other platforms
+
+# Dependencies: wget/curl, fuse
+
+# Color definitions
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+NC='\033[0m' # No Color
+
+# Handle errors
+handle_error() {
+ local message="$1"
+ printf "${RED}Error: $message${NC}\n"
+}
+
+# Check if necessary dependencies are installed
+check_dependencies() {
+ if [ -x "$(command -v wget)" ]; then
+ DOWNLOAD_COMMAND="wget"
+ elif [ -x "$(command -v curl)" ]; then
+ DOWNLOAD_COMMAND="curl"
+ else
+ printf "${RED}Error: Neither wget nor curl found. Please install one of them to continue!${NC}\n"
+ exit 1
+ fi
+}
+
+# Check for privilege escalation tools
+check_privilege_tools() {
+ if [ -x "$(command -v sudo)" ]; then
+ PRIVILEGE_TOOL="sudo"
+ elif [ -x "$(command -v doas)" ]; then
+ PRIVILEGE_TOOL="doas"
+ elif [ -x "$(command -v pkexec)" ]; then
+ PRIVILEGE_TOOL="pkexec"
+ elif [ -x "$(command -v dzdo)" ]; then
+ PRIVILEGE_TOOL="dzdo"
+ elif [ "$(id -u)" -eq 0 ]; then
+ PRIVILEGE_TOOL="" # root
+ else
+ PRIVILEGE_TOOL="" # No privilege escalation mechanism found
+ printf "\n${RED}Error: No privilege escalation tool (sudo, doas, pkexec, dzdo, or root privileges) found. You may not have sufficient permissions to run this script.${NC}\n"
+ printf "\nAttempt to continue Installation (might fail without a privilege escalation tool)? [yes/no] "
+ read continue_choice
+ case $continue_choice in
+ [Yy] | [Yy][Ee][Ss]) ;;
+ [Nn] | [Nn][Oo]) exit ;;
+ *) handle_error "Invalid choice. Exiting..." && exit ;;
+ esac
+ fi
+}
+
+# Check if Neovim is already installed
+check_neovim_installed() {
+ if [ -x "$(command -v nvim)" ]; then
+ return 0 # Neovim is installed
+ else
+ return 1 # Neovim is not installed
+ fi
+}
+
+# Nightly version
+nightly_version() {
+ local url="https://github.com/neovim/neovim/releases/download/nightly/nvim-linux-x86_64.appimage"
+ install_neovim "$url"
+ local version_output=$(nvim --version)
+ version_id="Nightly $(echo "$version_output" | grep -oP 'NVIM \d+\.\d+\.\d+')"
+}
+
+# Stable version
+stable_version() {
+ #local url="https://github.com/neovim/neovim/releases/download/stable/nvim.appimage"
+ local url="https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.appimage"
+ install_neovim "$url"
+ local version_output=$(nvim --version)
+ version_id="Stable $(echo "$version_output" | grep -oP 'NVIM \d+\.\d+')"
+}
+
+# Specific version
+specific_version() {
+ local version="$1"
+
+ # Add 'v' prefix if not present
+ if [[ $version != v* ]]; then
+ version="v$version"
+ fi
+
+ local url="https://github.com/neovim/neovim/releases/download/$version/nvim-linux-x86_64.appimage"
+ install_neovim "$url"
+ local version_output=$(nvim --version)
+ version_id="Version $version $(echo "$version_output" | grep -oP 'NVIM \d+\.\d+\.\d+')"
+}
+
+# Download a file using wget or curl
+download_file() {
+ local url="$1"
+ local output="$2"
+
+ if [ "$DOWNLOAD_COMMAND" = "wget" ]; then
+ if ! "$DOWNLOAD_COMMAND" -q --show-progress -O "$output" "$url"; then
+ handle_error "Download failed. Exiting..."
+ exit 1
+ fi
+ elif [ "$DOWNLOAD_COMMAND" = "curl" ]; then
+ if ! "$DOWNLOAD_COMMAND" --progress-bar -# -o "$output" "$url"; then
+ handle_error "Download failed. Exiting..."
+ exit 1
+ fi
+ else
+ echo "Unsupported download command: $DOWNLOAD_COMMAND"
+ exit 1
+ fi
+}
+
+# Check if a specific version of Neovim exists
+version_exists() {
+ local version="$1"
+
+ # Add 'v' prefix if not present
+ if [[ $version != v* ]]; then
+ version="v$version"
+ fi
+
+ # Fetch all the release tags from GitHub
+ ALL_TAGS=$(curl -s "https://api.github.com/repos/neovim/neovim/tags" | grep '"name":' | cut -d '"' -f 4)
+
+ # Check if the desired version is in the list of release tags
+ if echo "$ALL_TAGS" | grep -q "$version"; then
+ return 0 # Version exists
+ else
+ return 1 # Version does not exist
+ fi
+}
+
+# Update Neovim to the latest version (nightly/stable)
+update_version() {
+ valid_choice=false
+ while [ "$valid_choice" = false ]; do
+ # Determine which version to update to (nightly/stable)
+ printf "Select version to install/update to:\n"
+ printf " 1. Nightly\n"
+ printf " 2. Stable\n"
+ printf " 3. Choose specific version by tag\n"
+ printf "Enter the number corresponding to your choice (1/2/3): "
+ read update_choice
+
+ case $update_choice in
+ 1)
+ version="Nightly"
+ nightly_version
+ valid_choice=true
+ ;;
+ 2)
+ version="Stable"
+ stable_version
+ valid_choice=true
+ ;;
+ 3)
+ # Ask user for specific version
+ read -p "Enter the specific version (e.g., v0.1.0): " version
+ # Normalize version
+ if [[ $version != v* ]]; then
+ version="v$version"
+ fi
+ # Check if the specific version exists on GitHub releases
+ if version_exists "$version"; then
+ # Install specific version
+ specific_version "$version" # Pass the normalized version to the function
+ valid_choice=true
+ else
+ printf "${RED}The specified version $version does not exist.${NC}\n"
+ fi
+ ;;
+
+ *)
+ handle_error "Invalid choice. Please enter a valid option (1, 2 or 3)."
+ ;;
+ esac
+ done
+
+}
+
+# Install Neovim
+install_neovim() {
+ local url="$1"
+ local install_action="$3"
+
+ if [ "$install_action" = "installed" ]; then
+ printf "Downloading and installing Neovim $version...\n"
+ else
+ printf "${GREEN}Updating Neovim to the latest version ($version)...${NC}\n"
+ fi
+
+ # Determine the platform-specific installation steps
+ case "$(uname -s)" in
+ Linux)
+ printf "Detected Linux OS.\n"
+ if [ -x "$(command -v fusermount)" ]; then
+ printf "FUSE is available. Downloading and running the AppImage...\n"
+ download_file "$url" "nvim.appimage"
+ chmod u+x nvim.appimage
+ "$PRIVILEGE_TOOL" cp nvim.appimage /usr/local/bin/nvim
+ "$PRIVILEGE_TOOL" mv nvim.appimage /usr/bin/nvim
+ else
+ printf "FUSE is not available. Downloading and extracting the AppImage...\n"
+ download_file "$url" "nvim.appimage"
+ chmod u+x nvim.appimage
+ ./nvim.appimage --appimage-extract
+ "$PRIVILEGE_TOOL" cp squashfs-root/usr/bin/nvim /usr/local/bin
+ "$PRIVILEGE_TOOL" mv squashfs-root/usr/bin/nvim /usr/bin
+ fi
+ ;;
+
+ Darwin)
+ printf "Detected macOS.\n"
+ download_file "$url" "nvim-macos.tar.gz"
+ xattr -c ./nvim-macos.tar.gz
+ tar xzvf nvim-macos.tar.gz
+ "$PRIVILEGE_TOOL" cp nvim-macos/bin/nvim /usr/local/bin
+ "$PRIVILEGE_TOOL" mv nvim-macos/bin/nvim /usr/bin/nvim
+ ;;
+
+ MINGW*)
+ printf "Detected Windows.\n"
+ download_file "$url" "nvim.appimage"
+ chmod +x nvim.appimage
+ if [ "$PRIVILEGE_TOOL" = "sudo" ]; then
+ "$PRIVILEGE_TOOL" cp nvim.appimage /usr/local/bin/nvim
+ "$PRIVILEGE_TOOL" mv /usr/local/bin/nvim /usr/bin
+ elif [ "$PRIVILEGE_TOOL" = "" ]; then
+ cp nvim.appimage /usr/local/bin/nvim
+ mv /usr/local/bin/nvim /usr/bin
+ else
+ printf "No privilege escalation tool found. Cannot install Neovim on Windows.\n"
+ fi
+ ;;
+
+ *)
+ printf "Unsupported operating system.\n"
+ exit 1
+ ;;
+ esac
+ # Check if the installation was successful
+ if [ $? -eq 0 ]; then
+ if [ "$install_action" = "installed" ]; then
+ printf "${GREEN}Neovim $version has been installed successfully!${NC}\n"
+ else
+ printf "${GREEN}Neovim has been updated successfully to $version!${NC}\n"
+ fi
+ else
+ printf "${RED}Error: Neovim installation/update failed.${NC}\n"
+ exit 1
+ fi
+}
+
+# Uninstall Neovim
+uninstall_neovim() {
+ printf "${RED}Uninstalling Neovim...${NC}\n"
+
+ # Detect the operating system to determine the appropriate uninstallation method
+ case "$(uname -s)" in
+ Linux)
+ printf "Detected Linux OS.\n"
+ "$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
+ "$PRIVILEGE_TOOL" rm /usr/bin/nvim
+ ;;
+
+ Darwin)
+ printf "Detected macOS.\n"
+ "$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
+ "$PRIVILEGE_TOOL" rm /usr/bin/nvim
+ ;;
+
+ MINGW*)
+ printf "Detected Windows.\n"
+ if [ "$PRIVILEGE_TOOL" = "sudo" ]; then
+ "$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
+ "$PRIVILEGE_TOOL" rm /usr/bin/nvim
+ else
+ [ "$PRIVILEGE_TOOL" = "" ]
+ rm /usr/local/bin/nvim
+ rm /usr/bin/nvim
+ fi
+ ;;
+ *)
+ printf "Unsupported operating system.\n"
+ ;;
+ esac
+
+ printf "${GREEN}Neovim has been uninstalled successfully!${NC}\n"
+}
+
+# Check if Neovim is running
+check_neovim_running() {
+ if pgrep nvim >/dev/null; then
+ printf "${RED}Error: Neovim is currently running. Please close Neovim before proceeding.${NC}\n"
+ read -p "Do you want to forcefully terminate Neovim and continue? [yes/no] " terminate_choice
+
+ case $terminate_choice in
+ [Yy] | [Yy][Ee][Ss])
+ pkill nvim # Forcefully terminate Neovim
+ ;;
+ [Nn] | [Nn][Oo])
+ echo "Exiting..."
+ exit 1
+ ;;
+ *)
+ handle_error "Invalid choice."
+ ;;
+ esac
+ fi
+}
+
+check_neovim_running
+
+# Define the variable to control the prompt
+SHOW_PROMPT=1
+
+# Check if necessary dependencies are installed
+check_dependencies
+
+# Check for privilege escalation tools
+check_privilege_tools
+
+# Check if Neovim is already installed and ask the user if want to install it
+if check_neovim_installed; then
+ printf "${GREEN}Neovim is already installed!${NC}\n"
+else
+ printf "${RED}Neovim is not installed.${NC}\n"
+ read -p "Install Neovim? (y/n): " install_choice
+
+ case $install_choice in
+ [Yy])
+ update_version
+ ;;
+ [Nn])
+ echo "Exiting..."
+ exit
+ ;;
+ *)
+ handle_error "Invalid choice. Please enter 'y' for yes or 'n' for no."
+ ;;
+ esac
+fi
+
+# Check for updates and display breaking changes
+check_version_updates() {
+ local latest_version_url="https://api.github.com/repos/neovim/neovim/releases/latest"
+ local latest_version=""
+
+ if [ -x "$(command -v curl)" ]; then
+ latest_version=$(curl -sSL "$latest_version_url" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+ elif [ -x "$(command -v wget)" ]; then
+ latest_version=$(wget -qO - "$latest_version_url" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+ else
+ printf "${RED}Error: Neither curl nor wget found. Please install one of them to continue!${NC}\n"
+ exit 1
+ fi
+
+ if version_exists "$latest_version"; then
+ printf "${GREEN}An update is available!${NC}\n"
+ display_breaking_changes "$latest_version"
+ else
+ printf "You have the latest version of Neovim.\n"
+ fi
+}
+
+# To display breaking changes for a specific version
+display_breaking_changes() {
+ local version="$1"
+ local changelog_url="https://github.com/neovim/neovim/releases/tag/$version"
+ local changelog=""
+
+ if [ -x "$(command -v curl)" ]; then
+ changelog=$(curl -sSL "$changelog_url" | grep -oE '<h1>Breaking Changes.*?</ul>' | sed 's/<[^>]*>//g')
+ elif [ -x "$(command -v wget)" ]; then
+ changelog=$(wget -qO - "$changelog_url" | grep -oE '<h1>Breaking Changes.*?</ul>' | sed 's/<[^>]*>//g')
+ else
+ printf "${RED}Error: Neither curl nor wget found. Please install one of them to continue!${NC}\n"
+ exit 1
+ fi
+
+ printf "\nBreaking Changes in Neovim $version:\n"
+ printf "$changelog\n"
+}
+
+# Main loop
+while [ "$SHOW_PROMPT" -gt 0 ]; do
+ printf "Select an option:\n"
+ printf " 1. Install/update Neovim\n"
+ printf " 2. Check for updates\n"
+ printf " 3. Uninstall Neovim\n"
+ printf " 4. Run Neovim\n"
+ printf " 5. Quit\n"
+ read -p "Enter a number or press 'q' to quit: " choice
+
+ case $choice in
+ 1)
+ update_version
+ ;;
+ 2)
+ check_version_updates
+ ;;
+ 3)
+ uninstall_neovim
+ ;;
+ 4)
+ nvim
+ ;;
+ 5 | [Qq])
+ echo "Exiting..."
+ exit
+ ;;
+ *)
+ handle_error "Invalid choice. Please choose a valid option by entering the corresponding number or press 'q' to 'quit'."
+ ;;
+ esac
+done
diff --git a/utils/pack b/utils/pack
new file mode 100755
index 0000000..4b8760c
--- /dev/null
+++ b/utils/pack
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+# Created By: srdusr
+# Created On: Wed 05 Feb 2023 01:24:37 AM CAT
+# Project: bspwm scratchpad (pack) with tmux session
+
+### Alternative method
+
+#if id="$(xdo id -N pack)"; then
+# bspc node "$id" -g hidden -f
+#else
+# #kitty --class "pack" -e tmux new-session -A -s pack -e bash >/dev/null 2>&1 &
+# wezterm start --class "pack" -e tmux new-session -A -s pack -e bash >/dev/null 2>&1 &
+#fi
+
+#- - - - - - - - - -
+
+### Alternative method
+
+#id=$(xdotool search --class pack)
+#if [ "$id" = "" ]; then
+# #kitty --class "pack" -e tmux new-session -A -s pack -e bash > /dev/null 2>&1 &
+# alacritty --class "pack" -e tmux new-session -A -s pack -e bash >/dev/null 2>&1 &
+#else
+# if [ ! -f /tmp/hide_hud ]; then
+# touch /tmp/hide_hud && xdo hide "$id"
+# elif [ -f /tmp/hide_hud ]; then
+# rm /tmp/hide_hud && xdo show "$id"
+# fi
+#fi
+
+
+
+# Set the environment variables to x11 to allow working in Wayland
+export GDK_BACKEND=x11
+export QT_QPA_PLATFORM=xcb
+#export WAYLAND_DISPLAY=""
+export WINIT_UNIX_BACKEND=x11
+
+# Supported terminals and dropdown class
+supported_terminals=("wezterm" "kitty" "alacritty")
+
+# Check if any supported terminal with scratchpad class is running
+for term in "${supported_terminals[@]}"; do
+ if pgrep -f "$term.*--class pack" >/dev/null; then
+ my_term="$term"
+ break
+ fi
+done
+
+# If no supported terminal is running, start the first available one
+if [ "$my_term" = "" ]; then
+ for term in "${supported_terminals[@]}"; do
+ if command -v "$term" >/dev/null 2>&1; then
+ my_term="$term"
+ break
+ fi
+ done
+ if [ "$my_term" = "" ]; then
+ echo "No supported terminal found." && exit 1
+ fi
+
+ # Start terminal with scratchpad class
+ case "$my_term" in
+ "wezterm") wezterm start --class pack -e tmux new-session -A -s pack -e bash & ;;
+ "kitty") kitty --class pack tmux new-session -A -s pack -e bash & ;;
+ "alacritty") alacritty --class pack -e tmux new-session -A -s pack -e bash & ;;
+
+ esac
+fi
+
+# Get the window ID of the scratchpad terminal
+id="$(xdo id -N pack)"
+
+# Toggle scratchpad terminal visibility
+if [ "$id" != "" ]; then
+ if xwininfo -id "$id" | grep "Map State: IsViewable" >/dev/null; then
+ # Scratchpad is visible, hide it
+ dimensions="$(xwininfo -id "$id" | awk '/Width:|Height:/ { printf("%s=%s;", tolower($1), $2) }')"
+ xdo hide "$id" 2>/dev/null
+ else
+ # Scratchpad is hidden, show it and restore dimensions
+ xdo show "$id"
+ xdotool windowsize "$id" "$(echo "$dimensions" | tr ';' ' ')" 2>/dev/null
+ xdotool windowactivate "$id"
+ xdotool windowfocus "$id"
+ fi
+fi
diff --git a/utils/rofi-network-manager.sh b/utils/rofi-network-manager.sh
new file mode 100755
index 0000000..61106d2
--- /dev/null
+++ b/utils/rofi-network-manager.sh
@@ -0,0 +1,252 @@
+#!/bin/bash
+
+# Credit: https://github.com/P3rf/rofi-network-manager
+
+# Default Values
+LOCATION=0
+QRCODE_LOCATION=$LOCATION
+Y_AXIS=0
+X_AXIS=0
+NOTIFICATIONS="off"
+QRCODE_DIR="/tmp/"
+WIDTH_FIX_MAIN=1
+WIDTH_FIX_STATUS=10
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PASSWORD_ENTER="if connection is stored,hit enter/esc."
+WIRELESS_INTERFACES=("$(nmcli device | awk '$2=="wifi" {print $1}')")
+WIRELESS_INTERFACES_PRODUCT=()
+WLAN_INT=0
+WIRED_INTERFACES=("$(nmcli device | awk '$2=="ethernet" {print $1}')")
+WIRED_INTERFACES_PRODUCT=()
+ASCII_OUT=false
+CHANGE_BARS=false
+SIGNAL_STRENGTH_0="0"
+SIGNAL_STRENGTH_1="1"
+SIGNAL_STRENGTH_2="12"
+SIGNAL_STRENGTH_3="123"
+SIGNAL_STRENGTH_4="1234"
+VPN_PATTERN='(wireguard|vpn)'
+function initialization() {
+ # Try to source configuration files from .config/rofi/
+ if [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/rofi-network-manager.conf" ]]; then
+ source "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/rofi-network-manager.conf"
+ RASI_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/rofi/rofi-network-manager.rasi"
+ elif [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/rofi-network-manager.rasi" ]]; then
+ source "${XDG_CONFIG_HOME:-$HOME/.config}/rofi/rofi-network-manager.rasi"
+ else
+ # Fallback to using files in the script's directory
+ source "$DIR/rofi-network-manager.conf" || source "$DIR/rofi-network-manager.conf"
+ [[ -f "$DIR/rofi-network-manager.rasi" ]] && RASI_DIR="$DIR/rofi-network-manager.rasi"
+ fi
+ for i in "${WIRELESS_INTERFACES[@]}"; do WIRELESS_INTERFACES_PRODUCT+=("$(nmcli -f general.product device show "$i" | awk '{print $2}')"); done
+ for i in "${WIRED_INTERFACES[@]}"; do WIRED_INTERFACES_PRODUCT+=("$(nmcli -f general.product device show "$i" | awk '{print $2}')"); done
+ wireless_interface_state && ethernet_interface_state
+}
+function notification() {
+ [[ "$NOTIFICATIONS" == "true" && -x "$(command -v notify-send)" ]] && notify-send -r "5" -u "normal" "$1" "$2"
+}
+function wireless_interface_state() {
+
+ [[ ${#WIRELESS_INTERFACES[@]} -eq "0" ]] || {
+ ACTIVE_SSID=$(nmcli device status | grep "^${WIRELESS_INTERFACES[WLAN_INT]}." | awk '{print $4}')
+ WIFI_CON_STATE=$(nmcli device status | grep "^${WIRELESS_INTERFACES[WLAN_INT]}." | awk '{print $3}')
+ { [[ "$WIFI_CON_STATE" == "unavailable" ]] && WIFI_LIST="***Wi-Fi Disabled***" && WIFI_SWITCH="~Wi-Fi On" && OPTIONS="${WIFI_LIST}\n${WIFI_SWITCH}\n~Scan\n"; } || { [[ "$WIFI_CON_STATE" =~ "connected" ]] && {
+ PROMPT=${WIRELESS_INTERFACES_PRODUCT[WLAN_INT]}[${WIRELESS_INTERFACES[WLAN_INT]}]
+ WIFI_LIST=$(nmcli --fields SSID,SECURITY,BARS device wifi list ifname "${WIRELESS_INTERFACES[WLAN_INT]}")
+ wifi_list
+ [[ "$ACTIVE_SSID" == "--" ]] && WIFI_SWITCH="~Scan\n~Manual/Hidden\n~Wi-Fi Off" || WIFI_SWITCH="~Scan\n~Disconnect\n~Manual/Hidden\n~Wi-Fi Off"
+ OPTIONS="${WIFI_LIST}\n${WIFI_SWITCH}\n"
+ }; }
+ }
+}
+function ethernet_interface_state() {
+ [[ ${#WIRED_INTERFACES[@]} -eq "0" ]] || {
+ WIRED_CON_STATE=$(nmcli device status | grep "ethernet" | head -1 | awk '{print $3}')
+ { [[ "$WIRED_CON_STATE" == "disconnected" ]] && WIRED_SWITCH="~Eth On"; } || { [[ "$WIRED_CON_STATE" == "connected" ]] && WIRED_SWITCH="~Eth Off"; } || { [[ "$WIRED_CON_STATE" == "unavailable" ]] && WIRED_SWITCH="***Wired Unavailable***"; } || { [[ "$WIRED_CON_STATE" == "connecting" ]] && WIRED_SWITCH="***Wired Initializing***"; }
+ OPTIONS="${OPTIONS}${WIRED_SWITCH}\n"
+ }
+}
+function rofi_menu() {
+ { [[ ${#WIRELESS_INTERFACES[@]} -gt "1" ]] && OPTIONS="${OPTIONS}~Change Wifi Interface\n~More Options"; } || { OPTIONS="${OPTIONS}~More Options"; }
+ { [[ "$WIRED_CON_STATE" == "connected" ]] && PROMPT="${WIRED_INTERFACES_PRODUCT}[$WIRED_INTERFACES]"; } || PROMPT="${WIRELESS_INTERFACES_PRODUCT[WLAN_INT]}[${WIRELESS_INTERFACES[WLAN_INT]}]"
+ SELECTION=$(echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_MAIN" "-a 0")
+ SSID=$(echo "$SELECTION" | sed "s/\s\{2,\}/\|/g" | awk -F "|" '{print $1}')
+ selection_action
+}
+function rofi_cmd() {
+ { [[ -n "${1}" ]] && WIDTH=$(echo -e "$1" | awk '{print length}' | sort -n | tail -1) && ((WIDTH += $2)) && ((WIDTH = WIDTH / 2)); } || { ((WIDTH = $2 / 2)); }
+ rofi -dmenu -i -location "$LOCATION" -yoffset "$Y_AXIS" -xoffset "$X_AXIS" "$3" -theme "$RASI_DIR" -theme-str 'window{width: '"$WIDTH"'em;}textbox-prompt-colon{str:"'"$PROMPT"':";}'"$4"''
+}
+function change_wireless_interface() {
+ { [[ ${#WIRELESS_INTERFACES[@]} -eq "2" ]] && { [[ $WLAN_INT -eq "0" ]] && WLAN_INT=1 || WLAN_INT=0; }; } || {
+ LIST_WLAN_INT=""
+ for i in "${!WIRELESS_INTERFACES[@]}"; do LIST_WLAN_INT=("${LIST_WLAN_INT[@]}${WIRELESS_INTERFACES_PRODUCT[$i]}[${WIRELESS_INTERFACES[$i]}]\n"); done
+ LIST_WLAN_INT[-1]=${LIST_WLAN_INT[-1]::-2}
+ CHANGE_WLAN_INT=$(echo -e "${LIST_WLAN_INT[@]}" | rofi_cmd "${LIST_WLAN_INT[@]}" "$WIDTH_FIX_STATUS")
+ for i in "${!WIRELESS_INTERFACES[@]}"; do [[ $CHANGE_WLAN_INT == "${WIRELESS_INTERFACES_PRODUCT[$i]}[${WIRELESS_INTERFACES[$i]}]" ]] && WLAN_INT=$i && break; done
+ }
+ wireless_interface_state && ethernet_interface_state
+ rofi_menu
+}
+function scan() {
+ [[ "$WIFI_CON_STATE" =~ "unavailable" ]] && change_wifi_state "Wi-Fi" "Enabling Wi-Fi connection" "on" && sleep 2
+ notification "-t 0 Wifi" "Please Wait Scanning"
+ WIFI_LIST=$(nmcli --fields SSID,SECURITY,BARS device wifi list ifname "${WIRELESS_INTERFACES[WLAN_INT]}" --rescan yes)
+ wifi_list
+ wireless_interface_state && ethernet_interface_state
+ notification "-t 1 Wifi" "Please Wait Scanning"
+ rofi_menu
+}
+function wifi_list() {
+ WIFI_LIST=$(echo -e "$WIFI_LIST" | awk -F' +' '{ if (!seen[$1]++) print}' | awk '$1!="--" {print}' | awk '$1 !~ "^'"$ACTIVE_SSID"'"')
+ [[ $ASCII_OUT == "true" ]] && WIFI_LIST=$(echo -e "$WIFI_LIST" | sed 's/\(..*\)\*\{4,4\}/\1▂▄▆█/g' | sed 's/\(..*\)\*\{3,3\}/\1▂▄▆_/g' | sed 's/\(..*\)\*\{2,2\}/\1▂▄__/g' | sed 's/\(..*\)\*\{1,1\}/\1▂___/g')
+ [[ $CHANGE_BARS == "true" ]] && WIFI_LIST=$(echo -e "$WIFI_LIST" | sed 's/\(.*\)▂▄▆█/\1'"$SIGNAL_STRENGTH_4"'/' | sed 's/\(.*\)▂▄▆_/\1'"$SIGNAL_STRENGTH_3"'/' | sed 's/\(.*\)▂▄__/\1'"$SIGNAL_STRENGTH_2"'/' | sed 's/\(.*\)▂___/\1'"$SIGNAL_STRENGTH_1"'/' | sed 's/\(.*\)____/\1'"$SIGNAL_STRENGTH_0"'/')
+}
+function change_wifi_state() {
+ notification "$1" "$2"
+ nmcli radio wifi "$3"
+}
+function change_wired_state() {
+ notification "$1" "$2"
+ nmcli device "$3" "$4"
+}
+function net_restart() {
+ notification "$1" "$2"
+ nmcli networking off && sleep 3 && nmcli networking on
+}
+function disconnect() {
+ ACTIVE_SSID=$(nmcli -t -f GENERAL.CONNECTION dev show "${WIRELESS_INTERFACES[WLAN_INT]}" | cut -d ':' -f2)
+ notification "$1" "You're now disconnected from Wi-Fi network '$ACTIVE_SSID'"
+ nmcli con down id "$ACTIVE_SSID"
+}
+function check_wifi_connected() {
+ [[ "$(nmcli device status | grep "^${WIRELESS_INTERFACES[WLAN_INT]}." | awk '{print $3}')" == "connected" ]] && disconnect "Connection_Terminated"
+}
+function connect() {
+ check_wifi_connected
+ notification "-t 0 Wi-Fi" "Connecting to $1"
+ { [[ $(nmcli dev wifi con "$1" password "$2" ifname "${WIRELESS_INTERFACES[WLAN_INT]}" | grep -c "successfully activated") -eq "1" ]] && notification "Connection_Established" "You're now connected to Wi-Fi network '$1'"; } || notification "Connection_Error" "Connection can not be established"
+}
+function enter_passwword() {
+ PROMPT="Enter_Password" && PASS=$(echo "$PASSWORD_ENTER" | rofi_cmd "$PASSWORD_ENTER" 4 "-password")
+}
+function enter_ssid() {
+ PROMPT="Enter_SSID" && SSID=$(rofi_cmd "" 40)
+}
+function stored_connection() {
+ check_wifi_connected
+ notification "-t 0 Wi-Fi" "Connecting to $1"
+ { [[ $(nmcli dev wifi con "$1" ifname "${WIRELESS_INTERFACES[WLAN_INT]}" | grep -c "successfully activated") -eq "1" ]] && notification "Connection_Established" "You're now connected to Wi-Fi network '$1'"; } || notification "Connection_Error" "Connection can not be established"
+}
+function ssid_manual() {
+ enter_ssid
+ [[ -n $SSID ]] && {
+ enter_passwword
+ { [[ -n "$PASS" ]] && [[ "$PASS" != "$PASSWORD_ENTER" ]] && connect "$SSID" "$PASS"; } || stored_connection "$SSID"
+ }
+}
+function ssid_hidden() {
+ enter_ssid
+ [[ -n $SSID ]] && {
+ enter_passwword && check_wifi_connected
+ [[ -n "$PASS" ]] && [[ "$PASS" != "$PASSWORD_ENTER" ]] && {
+ nmcli con add type wifi con-name "$SSID" ssid "$SSID" ifname "${WIRELESS_INTERFACES[WLAN_INT]}"
+ nmcli con modify "$SSID" wifi-sec.key-mgmt wpa-psk
+ nmcli con modify "$SSID" wifi-sec.psk "$PASS"
+ } || [[ $(nmcli -g NAME con show | grep -c "$SSID") -eq "0" ]] && nmcli con add type wifi con-name "$SSID" ssid "$SSID" ifname "${WIRELESS_INTERFACES[WLAN_INT]}"
+ notification "-t 0 Wifi" "Connecting to $SSID"
+ { [[ $(nmcli con up id "$SSID" | grep -c "successfully activated") -eq "1" ]] && notification "Connection_Established" "You're now connected to Wi-Fi network '$SSID'"; } || notification "Connection_Error" "Connection can not be established"
+ }
+}
+function interface_status() {
+ local -n INTERFACES="$1" && local -n INTERFACES_PRODUCT="$2"
+ for i in "${!INTERFACES[@]}"; do
+ CON_STATE=$(nmcli device status | grep "^${INTERFACES[$i]}." | awk '{print $3}')
+ INT_NAME=${INTERFACES_PRODUCT[$i]}[${INTERFACES[$i]}]
+ [[ "$CON_STATE" == "connected" ]] && STATUS="$INT_NAME:\n\t$(nmcli -t -f GENERAL.CONNECTION dev show "${INTERFACES[$i]}" | awk -F '[:]' '{print $2}') ~ $(nmcli -t -f IP4.ADDRESS dev show "${INTERFACES[$i]}" | awk -F '[:/]' '{print $2}')" || STATUS="$INT_NAME: ${CON_STATE^}"
+ echo -e "$STATUS"
+ done
+}
+function status() {
+ OPTIONS=""
+ [[ ${#WIRED_INTERFACES[@]} -ne "0" ]] && ETH_STATUS="$(interface_status WIRED_INTERFACES WIRED_INTERFACES_PRODUCT)" && OPTIONS="${OPTIONS}${ETH_STATUS}"
+ [[ ${#WIRELESS_INTERFACES[@]} -ne "0" ]] && WLAN_STATUS="$(interface_status WIRELESS_INTERFACES WIRELESS_INTERFACES_PRODUCT)" && { [[ -n ${OPTIONS} ]] && OPTIONS="${OPTIONS}\n${WLAN_STATUS}" || OPTIONS="${OPTIONS}${WLAN_STATUS}"; }
+ ACTIVE_VPN=$(nmcli -g NAME,TYPE con show --active | awk '/:'"$VPN_PATTERN"'/ {sub(/:'"$VPN_PATTERN"'.*/, ""); print}')
+ [[ -n $ACTIVE_VPN ]] && OPTIONS="${OPTIONS}\n${ACTIVE_VPN}[VPN]: $(nmcli -g ip4.address con show "$ACTIVE_VPN" | awk -F '[:/]' '{print $1}')"
+ echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_STATUS" "" "mainbox{children:[listview];}"
+}
+function share_pass() {
+ SSID=$(nmcli dev wifi show-password | grep -oP '(?<=SSID: ).*' | head -1)
+ PASSWORD=$(nmcli dev wifi show-password | grep -oP '(?<=Password: ).*' | head -1)
+ OPTIONS="SSID: ${SSID}\nPassword: ${PASSWORD}"
+ [[ -x "$(command -v qrencode)" ]] && OPTIONS="${OPTIONS}\n~QrCode"
+ SELECTION=$(echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_STATUS" "-a -1" "mainbox{children:[listview];}")
+ selection_action
+}
+function gen_qrcode() {
+ DIRECTIONS=("Center" "Northwest" "North" "Northeast" "East" "Southeast" "South" "Southwest" "West")
+ TMP_SSID="${SSID// /_}"
+ [[ -e $QRCODE_DIR$TMP_SSID.png ]] || qrencode -t png -o "$QRCODE_DIR$TMP_SSID".png -l H -s 25 -m 2 --dpi=192 "WIFI:S:""$SSID"";T:""$(nmcli dev wifi show-password | grep -oP '(?<=Security: ).*' | head -1)"";P:""$PASSWORD"";;"
+ rofi_cmd "" "0" "" "entry{enabled:false;}window{location:""${DIRECTIONS[QRCODE_LOCATION]}"";border-radius:6mm;padding:1mm;width:100mm;height:100mm;
+ background-image:url(\"$QRCODE_DIR$TMP_SSID.png\",both);}"
+}
+function manual_hidden() {
+ OPTIONS="~Manual\n~Hidden" && SELECTION=$(echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_STATUS" "" "mainbox{children:[listview];}")
+ selection_action
+}
+function vpn() {
+ ACTIVE_VPN=$(nmcli -g NAME,TYPE con show --active | awk '/:'"$VPN_PATTERN"'/ {sub(/:'"$VPN_PATTERN"'.*/, ""); print}')
+ [[ $ACTIVE_VPN ]] && OPTIONS="~Deactive $ACTIVE_VPN" || OPTIONS="$(nmcli -g NAME,TYPE connection | awk '/:'"$VPN_PATTERN"'/ {sub(/:'"$VPN_PATTERN"'.*/, ""); print}')"
+ VPN_ACTION=$(echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_STATUS" "" "mainbox {children:[listview];}")
+ [[ -n "$VPN_ACTION" ]] && { { [[ "$VPN_ACTION" =~ "~Deactive" ]] && nmcli connection down "$ACTIVE_VPN" && notification "VPN_Deactivated" "$ACTIVE_VPN"; } || {
+ notification "-t 0 Activating_VPN" "$VPN_ACTION"
+ VPN_OUTPUT=$(nmcli connection up "$VPN_ACTION" 2>/dev/null)
+ { [[ $(echo "$VPN_OUTPUT" | grep -c "Connection successfully activated") -eq "1" ]] && notification "VPN_Successfully_Activated" "$VPN_ACTION"; } || notification "Error_Activating_VPN" "Check your configuration for $VPN_ACTION"
+ }; }
+}
+function more_options() {
+ OPTIONS=""
+ [[ "$WIFI_CON_STATE" == "connected" ]] && OPTIONS="~Share Wifi Password\n"
+ OPTIONS="${OPTIONS}~Status\n~Restart Network"
+ [[ $(nmcli -g NAME,TYPE connection | awk '/:'"$VPN_PATTERN"'/ {sub(/:'"$VPN_PATTERN"'.*/, ""); print}') ]] && OPTIONS="${OPTIONS}\n~VPN"
+ [[ -x "$(command -v nm-connection-editor)" ]] && OPTIONS="${OPTIONS}\n~Open Connection Editor"
+ SELECTION=$(echo -e "$OPTIONS" | rofi_cmd "$OPTIONS" "$WIDTH_FIX_STATUS" "" "mainbox {children:[listview];}")
+ selection_action
+}
+function selection_action() {
+ case "$SELECTION" in
+ "~Disconnect") disconnect "Connection_Terminated" ;;
+ "~Scan") scan ;;
+ "~Status") status ;;
+ "~Share Wifi Password") share_pass ;;
+ "~Manual/Hidden") manual_hidden ;;
+ "~Manual") ssid_manual ;;
+ "~Hidden") ssid_hidden ;;
+ "~Wi-Fi On") change_wifi_state "Wi-Fi" "Enabling Wi-Fi connection" "on" ;;
+ "~Wi-Fi Off") change_wifi_state "Wi-Fi" "Disabling Wi-Fi connection" "off" ;;
+ "~Eth Off") change_wired_state "Ethernet" "Disabling Wired connection" "disconnect" "$WIRED_INTERFACES" ;;
+ "~Eth On") change_wired_state "Ethernet" "Enabling Wired connection" "connect" "$WIRED_INTERFACES" ;;
+ "***Wi-Fi Disabled***") ;;
+ "***Wired Unavailable***") ;;
+ "***Wired Initializing***") ;;
+ "~Change Wifi Interface") change_wireless_interface ;;
+ "~Restart Network") net_restart "Network" "Restarting Network" ;;
+ "~QrCode") gen_qrcode ;;
+ "~More Options") more_options ;;
+ "~Open Connection Editor") nm-connection-editor ;;
+ "~VPN") vpn ;;
+ *)
+ [[ -n "$SELECTION" ]] && [[ "$WIFI_LIST" =~ .*"$SELECTION".* ]] && {
+ [[ "$SSID" == "*" ]] && SSID=$(echo "$SELECTION" | sed "s/\s\{2,\}/\|/g " | awk -F "|" '{print $3}')
+ { [[ "$ACTIVE_SSID" == "$SSID" ]] && nmcli con up "$SSID" ifname "${WIRELESS_INTERFACES[WLAN_INT]}"; } || {
+ [[ "$SELECTION" =~ "WPA2" ]] || [[ "$SELECTION" =~ "WEP" ]] && enter_passwword
+ { [[ -n "$PASS" ]] && [[ "$PASS" != "$PASSWORD_ENTER" ]] && connect "$SSID" "$PASS"; } || stored_connection "$SSID"
+ }
+ }
+ ;;
+ esac
+}
+function main() {
+ initialization && rofi_menu
+}
+main
diff --git a/utils/root.sh b/utils/root.sh
new file mode 100755
index 0000000..a7807bc
--- /dev/null
+++ b/utils/root.sh
@@ -0,0 +1,152 @@
+#!/bin/bash
+
+# Created By: srdusr
+# Created On: Mon 19 Feb 2025 14:18:00 PM CAT
+# Project: Backup and restore system files to/from home extras (system dotfiles) directory
+
+# Dependencies: None
+# NOTE: The backups will be stored in the ~/extras directory, preserving the original file structure. Run as sudo or be prompted for password
+# Example usage:
+# To backup a specific file: root.sh --backup /some_directory/some_file.conf
+# To restore a specific file: root.sh --restore ~/extras/some_directory/some_file.conf
+# To restore all files: root.sh --restore
+#
+
+# Use $SUDO_USER to get the original user when run with sudo, or fall back to the current user if not
+BASE_DIR="/home/${SUDO_USER:-$(whoami)}/extras"
+
+if [ "$EUID" -eq 0 ] && [ "$SUDO_USER" = "" ]; then
+ echo "You are running this script directly as root, not through sudo!"
+ exit 1
+fi
+
+if [ "$EUID" -ne 0 ]; then
+ echo "Elevating to sudo..."
+ exec sudo "$0" "$@" # Re-run the script with sudo
+fi
+
+# Create directories if they do not exist
+create_directory() {
+ local dir=$1
+ if [ ! -d "$dir" ]; then
+ echo "Creating directory: $dir"
+ mkdir -p "$dir"
+ else
+ echo "Directory already exists: $dir"
+ fi
+}
+
+# Backup files
+backup_to_extras() {
+ local src=$1
+
+ # Ensure the file or directory exists
+ if [ -e "$src" ]; then
+ # Strip the leading / from src to avoid double slashes
+ local stripped_src="${src#/}"
+
+ # Determine the destination path
+ dest_dir="$BASE_DIR/$(dirname "$stripped_src")" # Get the directory part of the source
+ dest_file="$BASE_DIR/$stripped_src" # Get the full destination file path
+
+ # Debug: Print paths
+ echo "Source file: $src"
+ echo "Destination directory: $dest_dir"
+ echo "Destination file: $dest_file"
+
+ # Create the necessary directories in extras if they don't exist
+ create_directory "$dest_dir"
+
+ # Backup the file to extras
+ echo "Backing up $src to $dest_file"
+ cp -p "$src" "$dest_file"
+
+ # Set permission to user
+ chown "$SUDO_USER:$SUDO_USER" "$dest_file"
+
+ echo "Backup of $src completed."
+ else
+ echo "Error: The file or directory '$src' does not exist."
+ fi
+}
+
+# Restore files
+restore_from_extras() {
+ local src=$1
+
+ # Ensure the file or directory exists in extras
+ if [ -e "$src" ]; then
+ # Strip the leading / from src to avoid double slashes
+ local stripped_src="${src#/}"
+
+ # Determine the destination path
+ dest_dir="/$(dirname "$stripped_src")" # Get the directory part of the source
+ dest_file="/$stripped_src" # Get the full destination file path
+
+ # Debug: Print paths
+ echo "Source file: $src"
+ echo "Destination directory: $dest_dir"
+ echo "Destination file: $dest_file"
+
+ # Create the necessary directories in the system if they don't exist
+ create_directory "$dest_dir"
+
+ # Backup the file if it exists before restoring
+ if [ -e "$dest_file" ]; then
+ echo "File $dest_file exists, creating a backup..."
+ mv "$dest_file" "$dest_file.bak"
+ echo "Backup created at $dest_file.bak"
+ fi
+
+ # Restore the file from extras
+ echo "Restoring $src to $dest_file"
+ cp -p "$BASE_DIR/$stripped_src" "$dest_file"
+
+ # Set permissions for the restored file
+ chmod 644 "$dest_file"
+
+ echo "Restore of $src completed."
+ else
+ echo "Error: The file or directory '$src' does not exist in extras."
+ fi
+}
+
+# Restore all files from extras
+restore_all_from_extras() {
+ echo "Restoring all files and directories from extras..."
+
+ # Loop over all files and directories in BASE_DIR and restore them
+ find "$BASE_DIR" -type f | while read -r file; do
+ restore_from_extras "$file"
+ done
+
+ echo "Restore completed."
+}
+
+# Backup system files based on user input
+if [ "$1" == "--backup" ]; then
+ if [ "$2" = "" ]; then
+ echo "Error: Please specify the file or directory to backup."
+ exit 1
+ fi
+
+ # Perform the backup
+ echo "Backing up system files to extras..."
+ backup_to_extras "$2"
+ echo "Backup completed."
+
+ # Restore system files based on user input
+elif [ "$1" == "--restore" ]; then
+ if [ "$2" = "" ]; then
+ # If no specific file is provided, restore everything
+ restore_all_from_extras
+ else
+ # Restore a specific file or directory
+ echo "Restoring system files from extras..."
+ restore_from_extras "$2"
+ echo "Restore completed."
+ fi
+
+else
+ echo "Invalid option. Use '--backup' to backup or '--restore' to restore."
+fi
diff --git a/utils/run_with_display.sh b/utils/run_with_display.sh
new file mode 100755
index 0000000..5f1f3a0
--- /dev/null
+++ b/utils/run_with_display.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+run_with_display() {
+ output=$("$@" 2>&1)
+ exit_status=$?
+
+ if [[ $exit_status -ne 0 && ("$output" =~ "cannot open display" || "$output" =~ "DISPLAY environment variable is missing") ]]; then
+ DISPLAY=:0 "$@"
+ else
+ echo "$output"
+ return $exit_status
+ fi
+}
+
+# Call this script with any command you want to run
+command=$1
+shift
+run_with_display "$command" "$@"
+
diff --git a/utils/scratchpad b/utils/scratchpad
new file mode 100755
index 0000000..d47dafe
--- /dev/null
+++ b/utils/scratchpad
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+# Created By: srdusr
+# Created On: Tue 07 Mar 2023 15:06:47 PM CAT
+# Project: Agnostic scratchpad/dropdown terminal that works on most window managers
+
+# Dependencies: wmctrl, xprop, xdo, xdotool
+# NOTE: Ensure script is included in system's path and can therefore be invoked with the command 'scratchpad'.
+# Furthermore make sure the terminal is using x11 as a backend in wayland to allow this to work.
+# Example: wezterm.lua: enable_wayland = false,
+# kitty.conf: linux_display_server x11
+
+# Set the environment variables to x11 to allow working in Wayland
+#export GDK_BACKEND=x11
+#export QT_QPA_PLATFORM=xcb
+#export WAYLAND_DISPLAY=""
+#export WINIT_UNIX_BACKEND=x11
+#export WAYLAND_DISPLAY=wayland-0
+
+# Supported terminals and dropdown class
+supported_terminals=("wezterm" "kitty" "alacritty")
+
+# Check if any supported terminal with scratchpad class is running
+for term in "${supported_terminals[@]}"; do
+ if pgrep -f "$term.*--class scratchpad" >/dev/null; then
+ my_term="$term"
+ break
+ fi
+done
+
+# If no supported terminal is running, start the first available one
+if [ "$my_term" = "" ]; then
+ for term in "${supported_terminals[@]}"; do
+ if command -v "$term" >/dev/null 2>&1; then
+ my_term="$term"
+ break
+ fi
+ done
+ if [ "$my_term" = "" ]; then
+ echo "No supported terminal found." && exit 1
+ fi
+
+ # Start terminal with scratchpad class
+ case "$my_term" in
+ "wezterm") wezterm start --class scratchpad -e tmux new-session -A -s tmux -e bash & ;;
+ "kitty") kitty --class scratchpad tmux new-session -A -s tmux -e bash & ;;
+ "alacritty") alacritty --class scratchpad -e tmux new-session -A -s tmux -e bash & ;;
+ esac
+fi
+
+# Get the window ID of the scratchpad terminal
+id="$(xdo id -N scratchpad)"
+# Get the ID of the currently focused window
+focused_id="$(xdotool getwindowfocus)"
+
+# Get class of the currently focused window
+focused_class="$(xprop -id "$focused_id" WM_CLASS 2>/dev/null | awk -F '"' '{print $4}')"
+
+# Toggle visible/hide and smart focus
+if [ "$id" != "" ]; then
+ if xwininfo -id "$id" | grep "Map State: IsViewable" >/dev/null; then
+ if [ "$focused_id" = "$id" ] || [ "$focused_class" = "scratchpad" ]; then
+ # Scratchpad is focused, hide it
+ dimensions="$(xwininfo -id "$id" | awk '/Width:|Height:/ { printf("%s=%s;", tolower($1), $2) }')"
+ xdo hide "$id" 2>/dev/null
+ else
+ # Scratchpad is visible but not focused
+ xdotool windowactivate "$id"
+ xdotool windowfocus "$id"
+ hyprctl dispatch focuswindow scratchpad
+ fi
+ else
+ # Scratchpad is hidden, show and focus it
+ xdo show "$id"
+ xdotool windowsize "$id" "$(echo "$dimensions" | tr ';' ' ')" 2>/dev/null
+ xdotool windowactivate "$id"
+ xdotool windowfocus "$id"
+ hyprctl dispatch focuswindow scratchpad
+ fi
+fi
+
+## Get the window ID of the PiP window by title
+#pip_id="$(xdo id -n "Picture-in-Picture")"
+#
+## Toggle scratchpad terminal visibility
+#if [ "$id" != "" ]; then
+# if xwininfo -id "$id" | grep "Map State: IsViewable" >/dev/null; then
+# # Scratchpad is visible, hide it
+# dimensions="$(xwininfo -id "$id" | awk '/Width:|Height:/ { printf("%s=%s;", tolower($1), $2) }')"
+# xdo hide "$id" 2>/dev/null
+# else
+# # Scratchpad is hidden, show it and restore dimensions
+# xdo show "$id"
+# xdotool windowsize "$id" "$(echo "$dimensions" | tr ';' ' ')" 2>/dev/null
+# xdotool windowactivate "$id"
+# xdotool windowfocus "$id"
+#
+# # Adjust layer based on PiP window presence
+# if [ "$pip_id" != "" ]; then
+# hyprctl dispatch layer "$id" 1
+# else
+# hyprctl dispatch layer "$id" 0
+# fi
+#
+# hyprctl dispatch focuswindow scratchpad
+# fi
+#fi
+
+## Get the window ID of the scratchpad terminal
+#id=$(hyprctl clients -j | jq -r '.[] | select(.class=="scratchpad").address')
+#
+## Toggle scratchpad terminal visibility
+#if [ -n "$id" ]; then
+# focused=$(hyprctl activewindow -j | jq -r '.address')
+# if [ "$focused" = "$id" ]; then
+# # Scratchpad is focused, minimize it
+# hyprctl dispatch move "address:$id workspace silent 0"
+# else
+# # Show scratchpad, set above normal windows but below PiP
+# hyprctl dispatch movetoworkspace current address:$id
+# hyprctl dispatch focuswindow address:$id
+# hyprctl dispatch layer "address:$id above"
+# hyprctl dispatch focuswindow address:$id
+# fi
+#fi
+
+## Get the window ID of the PiP window by title
+#pip_id=$(hyprctl clients -j | jq -r '.[] | select(.title=="Picture-in-Picture").address')
+#
+## Toggle scratchpad terminal visibility
+#if [ -n "$id" ]; then
+# focused=$(hyprctl activewindow -j | jq -r '.address')
+# if [ "$focused" = "$id" ]; then
+# # Scratchpad is focused, minimize it
+# hyprctl dispatch move "address:$id workspace silent 0"
+# else
+# # Show scratchpad, set above normal windows but below PiP
+# hyprctl dispatch movetoworkspace current address:$id
+# hyprctl dispatch focuswindow address:$id
+# if [ -n "$pip_id" ]; then
+# hyprctl dispatch layer "address:$id below"
+# else
+# hyprctl dispatch layer "address:$id above"
+# fi
+# hyprctl dispatch focuswindow address:$id
+# fi
+#fi
diff --git a/utils/screenshot b/utils/screenshot
new file mode 100755
index 0000000..b209574
--- /dev/null
+++ b/utils/screenshot
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+# === Config: directory for QEMU sockets ===
+QEMU_SOCK_DIR="/home/$(whoami)/virt/machines"
+
+# === Send 'print' key to QEMU monitor ===
+send_print_to_qemu() {
+ monitor_socket=$(find "$QEMU_SOCK_DIR" -maxdepth 1 -type s -name '*-monitor.socket' | head -n1)
+ if [ "$monitor_socket" = "" ]; then
+ echo "No QEMU monitor socket found."
+ return 1
+ fi
+ echo "Using QEMU monitor socket: $monitor_socket"
+ if ! printf "sendkey print\n" | socat - UNIX-CONNECT:"$monitor_socket"; then
+ echo "Failed to send key via socat."
+ return 1
+ fi
+ echo "Sent 'sendkey print' to QEMU successfully."
+ return 0
+}
+
+# === Detect if current window is QEMU (X11 only) ===
+if [ "$DISPLAY" != "" ] && command -v xprop >/dev/null 2>&1; then
+ win_id=$(xprop -root _NET_ACTIVE_WINDOW | awk -F' ' '{print $5}')
+ class=$(xprop -id "$win_id" WM_CLASS 2>/dev/null | awk -F'"' '{print $4}')
+ if [ "$class" = "qemu-system-x86_64" ]; then
+ send_print_to_qemu && exit 0
+ # if sending fails, optionally fallback or exit anyway
+ exit 1
+ fi
+fi
+#if command -v hyprctl >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then
+# focused_class="$(hyprctl activewindow -j | jq -r '.class' 2>/dev/null)"
+# if [ "$focused_class" = "qemu-system-x86_64" ]; then
+# send_print_to_qemu && exit 0
+# fi
+#fi
+
+DIR="$HOME/pictures/screenshots"
+OUTPUT_DIR="$HOME/documents/ocr_output"
+
+# Create the directories if they don't exist
+[ ! -d "$DIR" ] && mkdir -pv "$DIR"
+[ ! -d "$OUTPUT_DIR" ] && mkdir -pv "$OUTPUT_DIR"
+
+file="$DIR/screenshot_$(date '+%Y-%m-%d_%H-%M-%S').png"
+text_file="$OUTPUT_DIR/ocr_output_$(date '+%Y-%m-%d_%H-%M-%S')"
+
+copy_to_clipboard() {
+ if [ "$WAYLAND_DISPLAY" != "" ]; then
+ wl-copy <"$1"
+ elif [ "$DISPLAY" != "" ]; then
+ xclip -selection clipboard -i <"$1"
+ else
+ echo "No display server detected. Cannot copy to clipboard."
+ return 1
+ fi
+}
+
+case "$1" in
+screen) grim "$file" ;;
+output) slurp -o -r | grim -g - "$file" ;;
+area) slurp | grim -g - "$file" ;;
+output-area) slurp -o | grim -g - "$file" ;;
+ocr) slurp | grim -g - "$file" && tesseract "$file" "$text_file" ;;
+ocr-clipboard)
+ slurp | grim -g - "$file" && tesseract "$file" "$text_file"
+ if [ -f "$text_file.txt" ]; then
+ copy_to_clipboard "$text_file.txt"
+ CLIP_STATUS=$?
+ if [ "$CLIP_STATUS" -eq 0 ]; then
+ command rm -f "$text_file.txt"
+ notify-send -t 10000 --app-name "Screenshot" "OCR to Clipboard" "Text copied to clipboard."
+ echo "OCR output copied to clipboard and file deleted."
+ else
+ notify-send -t 10000 --app-name "Screenshot" "Clipboard Copy Failed" "Failed to copy text to clipboard."
+ echo "Failed to copy text to clipboard."
+ fi
+ else
+ notify-send -t 10000 --app-name "Screenshot" "OCR Error" "OCR process failed."
+ exit 1
+ fi
+ ;;
+*)
+ echo "Invalid argument"
+ notify-send -t 10000 --app-name "Screenshot" "Screenshot" "Something went wrong."
+ exit 1
+ ;;
+esac
+
+if [ "$1" = "ocr" ]; then
+ if [ -f "$text_file" ]; then
+ notify-send -t 10000 --app-name "Screenshot" "OCR Complete" "Text saved to $text_file"
+ echo "OCR output saved to: $text_file"
+ else
+ notify-send -t 10000 --app-name "Screenshot" "OCR Error" "OCR process failed."
+ exit 1
+ fi
+else
+ notify-send -t 10000 --app-name "Screenshot" "Screenshot" "Saved as $file"
+ echo "$file"
+fi
diff --git a/utils/sendkeys.awk b/utils/sendkeys.awk
new file mode 100755
index 0000000..16a3fa9
--- /dev/null
+++ b/utils/sendkeys.awk
@@ -0,0 +1,86 @@
+#!/usr/bin/env awk -f
+#
+# AWK script to send multiple `sendkey` commands to a QEMU virtual machine.
+# It writes at a rate of roughly 40 keys per second, due to lower delays
+# resulting in garbage output.
+#
+# It makes use of a TCP client created by an external utility, such as OpenBSD
+# Netcat, to interact with QEMU's monitor and send a stream of `sendkey`
+# commands. This is a practical way to transfer a small file or to script
+# interactions with a terminal user interface.
+
+BEGIN {
+ # Set default delay if not provided via command-line args
+ if (!delay) {
+ delay = 0.025
+ }
+
+ # Define key mappings for common characters and symbols
+ key["#"] = "backspace"
+ key[" "] = "tab"
+ key[" "] = "spc"
+ key["!"] = "shift-1"
+ key["\""] = "shift-apostrophe"
+ key["#"] = "shift-3"
+ key["$"] = "shift-4"
+ key["%"] = "shift-5"
+ key["&"] = "shift-7"
+ key["'"] = "apostrophe"
+ key["("] = "shift-9"
+ key[")"] = "shift-0"
+ key["*"] = "shift-8"
+ key["+"] = "shift-equal"
+ key[","] = "comma"
+ key["-"] = "minus"
+ key["."] = "dot"
+ key["/"] = "slash"
+ key[":"] = "shift-semicolon"
+ key[";"] = "semicolon"
+ key["<"] = "shift-comma"
+ key["="] = "equal"
+ key[">"] = "shift-dot"
+ key["?"] = "shift-slash"
+ key["@"] = "shift-2"
+
+ # Map numbers
+ for (i = 48; i < 48 + 10; ++i) {
+ number = sprintf("%c", i)
+ key[number] = number
+ }
+
+ # Map letters A-Z, including shift
+ for (i = 65; i < 65 + 26; ++i) {
+ key[sprintf("%c", i)] = sprintf("shift-%c", i + 32)
+ }
+
+ # Other symbols
+ key["["] = "bracket_left"
+ key["\\"] = "backslash"
+ key["]"] = "bracket_right"
+ key["^"] = "shift-6"
+ key["_"] = "shift-minus"
+ key["`"] = "grave_accent"
+ key["{"] = "shift-bracket_left"
+ key["|"] = "shift-backslash"
+ key["}"] = "shift-bracket_right"
+ key["~"] = "shift-grave_accent"
+ key[""] = "delete"
+
+ # Handle Super and Caps Lock key mappings (for remapping Caps to Super)
+ key["capslock"] = "super"
+ key["super"] = "super"
+
+ # Handle other keys if needed
+}
+
+{
+ split($0, chars, "")
+ for (i = 1; i <= length($0); i++) {
+ # Print sendkey command for the character, mapping it through the key[] array
+ if (key[chars[i]] != "") {
+ printf("sendkey %s\n", key[chars[i]])
+ }
+ system("sleep " delay) # Sleep for the defined delay
+ }
+ printf "sendkey ret\n" # Send "return" (enter) key at the end
+}
diff --git a/utils/sext b/utils/sext
new file mode 100755
index 0000000..b120929
--- /dev/null
+++ b/utils/sext
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+#Sext (Shutdown Exit)
+# List of package managers to check for
+package_managers=("emerge" "apt" "dnf" "pacman" "zypper")
+
+# Set how often to check (in seconds)
+check_interval=30
+
+# Check if any package manager is running
+is_package_manager_running() {
+ for pm in "${package_managers[@]}"; do
+ if pgrep -x "$pm" >/dev/null; then
+ return 0 # Return 0 (true) if any package manager is running
+ fi
+ done
+ return 1 # Return 1 (false) if no package manager is running
+}
+
+# Safely shutdown the system
+safe_shutdown() {
+ # Try using shutdown without sudo first
+ if shutdown -h now; then
+ echo "Shutdown initiated successfully using 'shutdown'."
+ # If shutdown fails, try using poweroff
+ elif poweroff; then
+ echo "Shutdown initiated successfully using 'poweroff'."
+ # If poweroff fails, try using sudo poweroff
+ elif sudo poweroff; then
+ echo "Shutdown initiated successfully with 'sudo poweroff'."
+ # If both shutdown and poweroff fail, try with sudo shutdown
+ elif sudo shutdown -h now; then
+ echo "Shutdown initiated successfully with 'sudo shutdown'."
+ else
+ echo "Shutdown command failed. Please check your system configuration."
+ fi
+}
+
+# Loop until no package manager process is running
+while is_package_manager_running; do
+ echo "Package manager is still running. Checking again in $check_interval seconds..."
+ sleep "$check_interval"
+done
+
+# Once the process completes, initiate a safe shutdown
+echo "Package manager has finished. Attempting to shutdown..."
+safe_shutdown
diff --git a/utils/track-books.sh b/utils/track-books.sh
new file mode 100755
index 0000000..f13add8
--- /dev/null
+++ b/utils/track-books.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Created By: srdusr
+# Created On: Wed 25 Oct 2023 13:45:52 CAT
+# Project: Simple script to track most recent books opened, mainly for neovim usage.
+
+# Dependencies: inotify-tools
+
+books_directory="$HOME/documents/books"
+recent_books_file="$HOME/.config/nvim/tmp/recent_books.txt"
+
+inotifywait -m -e CREATE -e OPEN -r "$books_directory" |
+ while read -r path action file; do
+ if [[ $file == *.pdf || $file == *.epub ]]; then
+ echo "$path/$file" >>"$recent_books_file"
+ # Remove duplicates and overwrite the recent_books_file
+ sort -u -o "$recent_books_file" "$recent_books_file"
+ fi
+ done
diff --git a/utils/umnt b/utils/umnt
new file mode 100755
index 0000000..6d9b788
--- /dev/null
+++ b/utils/umnt
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+# unmount disk
+set -e
+. ~/etc/colors/current
+
+lsblk -Po NAME,SIZE,MOUNTPOINT,FSTYPE,LABEL | while read -r a; do
+ eval "$a"
+
+ [ "$MOUNTPOINT" ] && ! grep -iq "\s$MOUNTPOINT\s" /etc/fstab &&
+ printf "%-4s:%s:%s:<- %s\n" \
+ "$NAME" \
+ "$SIZE" \
+ "${LABEL:-unnamed}" \
+ "${MOUNTPOINT//$HOME/\~}"
+
+ done | column -ts':' -o' ' | menu -p unmount | {
+ read -r NAME _
+ eval "$(lsblk -Po LABEL,MOUNTPOINT "/dev/$NAME")"
+ notify-send summary "<span color='#$red'>$NAME: $LABEL</span>\n${MOUNTPOINT/$HOME/\~}"
+ sudo umount "$MOUNTPOINT"
+ sudo rmdir "$HOME/dev/$NAME" || :
+}
diff --git a/utils/waypipe_app b/utils/waypipe_app
new file mode 100755
index 0000000..a8520bc
--- /dev/null
+++ b/utils/waypipe_app
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Usage: ./waypipe_app user@remote <app>
+# Example: ./waypipe_app user@remote gedit
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 user@remote <app> [args...]"
+ exit 1
+fi
+
+REMOTE=$1
+shift
+APP="$@"
+
+# Run the app remotely, forward display over SSH with waypipe
+waypipe ssh "$REMOTE" $APP
diff --git a/utils/wayvnc_session b/utils/wayvnc_session
new file mode 100755
index 0000000..1f2f30b
--- /dev/null
+++ b/utils/wayvnc_session
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# Usage: ./wayvnc_session [address] [port]
+# Default: 0.0.0.0 5900
+
+ADDR=${1:-0.0.0.0}
+PORT=${2:-5900}
+
+echo "Starting Wayland VNC server on $ADDR:$PORT"
+wayvnc $ADDR $PORT
diff --git a/utils/window_manager_name.sh b/utils/window_manager_name.sh
new file mode 100755
index 0000000..cfff9ee
--- /dev/null
+++ b/utils/window_manager_name.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+
+windowManagerName () {
+ local window=$(
+ xprop -root -notype
+ )
+
+ local identifier=$(
+ echo "${window}" |
+ awk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}'
+ )
+
+ local attributes=$(
+ xprop -id "${identifier}" -notype -f _NET_WM_NAME 8t
+ )
+
+ local name=$(
+ echo "${attributes}" |
+ grep "_NET_WM_NAME = " |
+ cut --delimiter=' ' --fields=3 |
+ cut --delimiter='"' --fields=2
+ )
+
+ echo "${name}"
+}
+
+
+windowManagerName
diff --git a/utils/xtouch b/utils/xtouch
new file mode 100755
index 0000000..a5eb23b
--- /dev/null
+++ b/utils/xtouch
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+check_valid() {
+ if [ -f "$1" ]; then
+ echo "The file "$1" already exists!"
+ exit 1
+ fi
+}
+
+create_script() {
+ touch "$1"
+ chmod +x "$1"
+ echo "$0: $2 script file $1 created with exec permissions"
+ echo -e '#!/usr/bin/env '"$2" > "$1"
+}
+
+usage() {
+ echo -e "Quickly create executable script\n"
+ echo "Usage:"
+ echo " xtouch [ -w FILE LANG ]"
+ echo -e " xtouch ( -h | --help )\n"
+ echo "Arguments:"
+ echo "FILE Name to give the scripts"
+ echo -e "LANG Language in which the script will be written\n"
+ echo "Options:"
+ echo " -w FILE LANG Creates a <LANG> executable script file named <FILE>."
+ echo " -h --help Show this screen."
+}
+
+case "$1" in
+ '-w')
+ check_valid "$2"
+ create_script "$2" "$3"
+ ;;
+ *)
+ usage
+ ;;
+esac