Merge branch 'main' into improved_navigation

This commit is contained in:
Chris Titus 2024-08-08 17:51:18 -05:00 committed by GitHub
commit ae2f734745
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1082 additions and 52 deletions

View File

@ -12,4 +12,6 @@ ignore:
- dependency-name: "actions/stale" - dependency-name: "actions/stale"
versions: '>= 9' versions: '>= 9'
- dependency-name: "actions/setup-python" - dependency-name: "actions/setup-python"
versions: '> 4' versions: '> 4'
- dependency-name: "crossterm"
versions: '> 0.27.0'

12
Cargo.lock generated
View File

@ -163,9 +163,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.11" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -173,9 +173,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.11" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -185,9 +185,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.11" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",

View File

@ -5,7 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
chrono = "0.4.33" chrono = "0.4.33"
clap = { version = "4.5.11", features = ["derive"] } clap = { version = "4.5.13", features = ["derive"] }
crossterm = "0.27.0" crossterm = "0.27.0"
ego-tree = "0.6.2" ego-tree = "0.6.2"
oneshot = "0.1.8" oneshot = "0.1.8"

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,27 @@
#!/bin/sh -e
. ./common-script.sh
makeDWM(){
cd $HOME && git clone https://github.com/ChrisTitusTech/dwm-titus.git # CD to Home directory to install dwm-titus
# This path can be changed (e.g. to linux-toolbox directory)
cd dwm-titus/ # Hardcoded path, maybe not the best.
sudo ./setup.sh # Run setup
sudo make clean install # Run make clean install
}
setupDWM() {
echo "Installing DWM-Titus if not already installed"
case "$PACKAGER" in # Install pre-Requisites
pacman)
sudo "$PACKAGER" -S --noconfirm --needed base-devel libx11 libxinerama libxft imlib2
;;
*)
sudo "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev
;;
esac
}
checkEnv
setupDWM
makeDWM

View File

@ -0,0 +1,51 @@
#!/bin/sh
. ./common-script.sh
# Function to install zsh
install_zsh() {
echo "Install ZSH if not already installed..."
if ! command_exists zsh; then
case "$PACKAGER" in
pacman)
sudo "$PACKAGER" -Sy --noconfirm zsh
;;
*)
sudo "$PACKAGER" install -y zsh
;;
esac
else
echo "ZSH is already installed."
fi
}
# Function to setup zsh configuration
setup_zsh_config() {
CONFIG_DIR="$HOME/.config/zsh"
ZSHRC_FILE="$CONFIG_DIR/.zshrc"
if [ ! -d "$CONFIG_DIR" ]; then
mkdir -p "$CONFIG_DIR"
fi
# Write the configuration to .zshrc
cat <<EOL >"$ZSHRC_FILE"
HISTFILE=~/.config/zsh/.histfile
HISTSIZE=5000
SAVEHIST=100000
setopt autocd extendedglob
unsetopt beep
bindkey -v
# Configure the prompt with embedded Solarized color codes
PROMPT='%F{32}%n%f%F{166}@%f%F{64}%m:%F{166}%~%f%F{15}$%f '
RPROMPT='%F{15}(%F{166}%D{%H:%M}%F{15})%f'
EOL
# Ensure /etc/zsh/zshenv sets ZDOTDIR to the user's config directory
echo 'export ZDOTDIR="$HOME/.config/zsh"' | sudo tee -a /etc/zsh/zshenv
}
checkEnv
setup_zsh_config
install_zsh

View File

@ -1,11 +1,13 @@
#!/bin/sh -e #!/bin/sh -e
. ./common-script.sh
installPkg() { installPkg() {
echo "Install UFW if not already installed..." echo "Install UFW if not already installed..."
if ! command_exists ufw; then if ! command_exists ufw; then
case ${PACKAGER} in case ${PACKAGER} in
pacman) pacman)
sudo "${PACKAGER}" -S --noconfirm ufw sudo "${PACKAGER}" -Sy --noconfirm ufw
;; ;;
*) *)
sudo "${PACKAGER}" install -y ufw sudo "${PACKAGER}" install -y ufw
@ -14,26 +16,33 @@ installPkg() {
else else
echo "UFW is already installed." echo "UFW is already installed."
fi fi
}
configureUFW() {
echo -e "${GREEN}Using Chris Titus Recommended Firewall Rules${RC}" echo -e "${GREEN}Using Chris Titus Recommended Firewall Rules${RC}"
sudo ufw limit 22/tcp
echo "Disabling UFW"
sudo ufw disable
echo "Limiting port 22/tcp (UFW)" echo "Limiting port 22/tcp (UFW)"
sudo ufw limit 22/tcp
sudo ufw allow 80/tcp
echo "Allowing port 80/tcp (UFW)" echo "Allowing port 80/tcp (UFW)"
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
echo "Allowing port 443/tcp (UFW)" echo "Allowing port 443/tcp (UFW)"
sudo ufw allow 443/tcp
sudo ufw default deny incoming
echo "Denying Incoming Packets by Default(UFW)" echo "Denying Incoming Packets by Default(UFW)"
sudo ufw default deny incoming
sudo ufw default allow outgoing
echo "Allowing Outcoming Packets by Default(UFW)" echo "Allowing Outcoming Packets by Default(UFW)"
sudo ufw default allow outgoing
sudo ufw enable sudo ufw enable
echo -e "${GREEN}Enabled Firewall with Baselines!${RC}" echo -e "${GREEN}Enabled Firewall with Baselines!${RC}"
} }
checkEnv checkEnv
installPkg installPkg
configureUFW

View File

@ -0,0 +1,28 @@
#!/bin/sh -e
. ./common-script.sh
removeSnaps() {
case $PACKAGER in
pacman)
sudo ${PACKAGER} -Rns snapd
;;
apt-get|nala)
sudo ${PACKAGER} autoremove --purge snapd
if [ "$ID" = ubuntu ]; then
sudo apt-mark hold snapd
fi
;;
dnf)
sudo ${PACKAGER} remove snapd
;;
zypper)
sudo ${PACKAGER} remove snapd
;;
*)
echo "removing snapd not implemented for this package manager"
esac
}
checkEnv
removeSnaps

View File

@ -0,0 +1,131 @@
#!/bin/bash
# Function to display colored text
colored_echo() {
local color=$1
local text=$2
case $color in
red) echo -e "\033[31m$text\033[0m" ;;
green) echo -e "\033[32m$text\033[0m" ;;
yellow) echo -e "\033[33m$text\033[0m" ;;
blue) echo -e "\033[34m$text\033[0m" ;;
*) echo "$text" ;;
esac
}
# Function to display the main menu
main_menu() {
while true; do
clear
colored_echo blue "Bluetooth Manager"
colored_echo blue "================="
echo "1. Scan for devices"
echo "2. Pair with a device"
echo "3. Connect to a device"
echo "4. Disconnect from a device"
echo "5. Remove a device"
echo "0. Exit"
echo -n "Choose an option: "
read -e choice
case $choice in
1) scan_devices ;;
2) pair_device ;;
3) connect_device ;;
4) disconnect_device ;;
5) remove_device ;;
0) exit 0 ;;
*) colored_echo red "Invalid option. Please try again." ;;
esac
done
}
# Function to scan for devices
scan_devices() {
clear
colored_echo yellow "Scanning for devices..."
bluetoothctl --timeout 10 scan on
devices=$(bluetoothctl devices)
if [ -z "$devices" ]; then
colored_echo red "No devices found."
else
colored_echo green "Devices found:"
echo "$devices"
fi
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to prompt for MAC address using numbers
prompt_for_mac() {
local action=$1
local command=$2
local prompt_msg=$3
local success_msg=$4
local failure_msg=$5
while true; do
clear
devices=$(bluetoothctl devices)
if [ -z "$devices" ]; then
colored_echo red "No devices available. Please scan for devices first."
echo "Press any key to return to the main menu..."
read -n 1
return
fi
# Display devices with numbers
IFS=$'\n' read -rd '' -a device_list <<<"$devices"
for i in "${!device_list[@]}"; do
echo "$((i+1)). ${device_list[$i]}"
done
echo "0. Exit to main menu"
echo -n "$prompt_msg"
read -e choice
# Validate the choice
if [[ $choice =~ ^[0-9]+$ ]] && [ "$choice" -le "${#device_list[@]}" ] && [ "$choice" -gt 0 ]; then
device=${device_list[$((choice-1))]}
mac=$(echo "$device" | awk '{print $2}')
if bluetoothctl info "$mac" > /dev/null 2>&1; then
bluetoothctl $command "$mac" && {
colored_echo green "$success_msg"
break
} || {
colored_echo red "$failure_msg"
}
else
colored_echo red "Invalid MAC address. Please try again."
fi
elif [ "$choice" -eq 0 ]; then
return
else
colored_echo red "Invalid choice. Please try again."
fi
done
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to pair with a device
pair_device() {
prompt_for_mac "pair" "pair" "Enter the number of the device to pair: " "Pairing with device completed." "Failed to pair with device."
}
# Function to connect to a device
connect_device() {
prompt_for_mac "connect" "connect" "Enter the number of the device to connect: " "Connecting to device completed." "Failed to connect to device."
}
# Function to disconnect from a device
disconnect_device() {
prompt_for_mac "disconnect" "disconnect" "Enter the number of the device to disconnect: " "Disconnecting from device completed." "Failed to disconnect from device."
}
# Function to remove a device
remove_device() {
prompt_for_mac "remove" "remove" "Enter the number of the device to remove: " "Removing device completed." "Failed to remove device."
}
# Initialize
main_menu

View File

@ -0,0 +1,32 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to auto-detect displays and set common resolution
auto_detect_displays() {
if confirm_action "Auto-detect displays and set common resolution?"; then
execute_command "xrandr --auto"
monitors=$(detect_connected_monitors)
first_monitor=$(echo "$monitors" | head -n 1)
common_resolutions=$(get_unique_resolutions "$first_monitor")
for monitor in $monitors; do
resolutions=$(get_unique_resolutions "$monitor")
common_resolutions=$(comm -12 <(echo "$common_resolutions") <(echo "$resolutions"))
done
if [ -z "$common_resolutions" ]; then
dialog --msgbox "No common resolution found among connected monitors." 10 60
return
fi
highest_resolution=$(echo "$common_resolutions" | sort -n -t'x' -k1,1 -k2,2 | tail -n 1)
for monitor in $monitors; do
echo "Setting resolution for $monitor to $highest_resolution"
execute_command "xrandr --output $monitor --mode $highest_resolution"
done
fi
}
auto_detect_displays

View File

@ -0,0 +1,57 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to change monitor orientation
change_orientation() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Change Monitor Orientation${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose a monitor to configure:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the number of the monitor: " monitor_choice
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Set Orientation for $monitor_name${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose orientation:${RESET}"
echo -e "1. ${CYAN}Normal${RESET}"
echo -e "2. ${CYAN}Left${RESET}"
echo -e "3. ${CYAN}Right${RESET}"
echo -e "4. ${CYAN}Inverted${RESET}"
read -p "Enter the number of the orientation: " orientation_choice
case $orientation_choice in
1) orientation="normal" ;;
2) orientation="left" ;;
3) orientation="right" ;;
4) orientation="inverted" ;;
*) echo -e "${RED}Invalid selection.${RESET}"; return ;;
esac
if confirm_action "Change orientation of ${CYAN}$monitor_name${RESET} to ${CYAN}$orientation${RESET}?"; then
echo -e "${GREEN}Changing orientation of $monitor_name to $orientation${RESET}"
execute_command "xrandr --output $monitor_name --rotate $orientation"
echo -e "${GREEN}Orientation changed successfully.${RESET}"
else
echo -e "${RED}Action canceled.${RESET}"
fi
}
# Call the change_orientation function
change_orientation

View File

@ -0,0 +1,59 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
# Function to disable a monitor
disable_monitor() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Disable Monitor${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose a monitor to disable:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the number of the monitor: " monitor_choice
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
echo -e "${RED}Warning: Disabling the monitor will turn it off and may affect your display setup.${RESET}"
if confirm_action "Do you really want to disable ${CYAN}$monitor_name${RESET}?"; then
echo -e "${GREEN}Disabling $monitor_name${RESET}"
execute_command "xrandr --output $monitor_name --off"
echo -e "${GREEN}Monitor $monitor_name disabled successfully.${RESET}"
else
echo -e "${RED}Action canceled.${RESET}"
fi
}
# Function to prompt for confirmation
confirm_action() {
local action="$1"
echo -e "${BOLD}${YELLOW}$action${RESET}"
read -p "Are you sure? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
return 0
else
return 1
fi
}
# Call the disable_monitor function
disable_monitor

View File

@ -0,0 +1,15 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to duplicate displays
duplicate_displays() {
primary=$(detect_connected_monitors | head -n 1)
for monitor in $(detect_connected_monitors | tail -n +2); do
if confirm_action "Duplicate $monitor to $primary?"; then
echo "Duplicating $monitor to $primary"
execute_command "xrandr --output $monitor --same-as $primary"
fi
done
}
duplicate_displays

View File

@ -0,0 +1,57 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
# Function to enable a monitor
enable_monitor() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Enable Monitor${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose a monitor to enable:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the number of the monitor: " monitor_choice
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
if confirm_action "Enable ${CYAN}$monitor_name${RESET}?"; then
echo -e "${GREEN}Enabling $monitor_name${RESET}"
execute_command "xrandr --output $monitor_name --auto"
echo -e "${GREEN}Monitor $monitor_name enabled successfully.${RESET}"
else
echo -e "${RED}Action canceled.${RESET}"
fi
}
# Function to prompt for confirmation
confirm_action() {
local action="$1"
echo -e "${BOLD}${YELLOW}$action${RESET}"
read -p "Are you sure? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
return 0
else
return 1
fi
}
# Call the enable_monitor function
enable_monitor

View File

@ -0,0 +1,15 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to extend displays
extend_displays() {
monitors=($(detect_connected_monitors))
for ((i=1; i<${#monitors[@]}; i++)); do
if confirm_action "Extend ${monitors[$i]} to the right of ${monitors[$((i-1))]}?"; then
echo "Extending ${monitors[$i]} to the right of ${monitors[$((i-1))]}"
execute_command "xrandr --output ${monitors[$i]} --right-of ${monitors[$((i-1))]}"
fi
done
}
extend_displays

View File

@ -0,0 +1,70 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to manage monitor arrangement
manage_arrangement() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Manage Monitor Arrangement${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose the monitor to arrange:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the number of the monitor to arrange: " monitor_choice
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
clear
echo -e "${YELLOW}Choose position relative to other monitors:${RESET}"
echo -e "1. ${CYAN}Left of${RESET}"
echo -e "2. ${CYAN}Right of${RESET}"
echo -e "3. ${CYAN}Above${RESET}"
echo -e "4. ${CYAN}Below${RESET}"
read -p "Enter the number of the position: " position_choice
case $position_choice in
1) position="--left-of" ;;
2) position="--right-of" ;;
3) position="--above" ;;
4) position="--below" ;;
*) echo -e "${RED}Invalid selection.${RESET}"; return ;;
esac
echo -e "${YELLOW}Choose the reference monitor:${RESET}"
for i in "${!monitor_array[@]}"; do
if [[ "${monitor_array[i]}" != "$monitor_name" ]]; then
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
fi
done
read -p "Enter the number of the reference monitor: " ref_choice
if ! [[ "$ref_choice" =~ ^[0-9]+$ ]] || (( ref_choice < 1 )) || (( ref_choice > ${#monitor_array[@]} )) || (( ref_choice == monitor_choice )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
ref_monitor="${monitor_array[ref_choice - 1]}"
if confirm_action "Arrange ${CYAN}$monitor_name${RESET} ${position} ${CYAN}$ref_monitor${RESET}?"; then
echo -e "${GREEN}Arranging $monitor_name ${position} $ref_monitor${RESET}"
execute_command "xrandr --output $monitor_name $position $ref_monitor"
echo -e "${GREEN}Arrangement updated successfully.${RESET}"
else
echo -e "${RED}Action canceled.${RESET}"
fi
}
# Call the manage_arrangement function
manage_arrangement

View File

@ -0,0 +1,22 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to reset scaling back to 1 (native resolution) for all monitors
reset_scaling() {
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Reset Monitor Scaling to Native Resolution${RESET}"
echo -e "${BLUE}=========================================${RESET}"
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
for monitor in "${monitor_array[@]}"; do
echo -e "${CYAN}Resetting scaling for $monitor to 1x1 (native resolution)${RESET}"
execute_command "xrandr --output $monitor --scale 1x1"
done
echo -e "${GREEN}All monitor scalings have been reset to 1x1.${RESET}"
}
# Call the reset_scaling function
reset_scaling

View File

@ -0,0 +1,43 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to scale smaller monitors to the highest resolution of a bigger monitor
scale_monitors() {
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Scale Monitors to Highest Resolution${RESET}"
echo -e "${BLUE}=========================================${RESET}"
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
# Get the highest resolution among all monitors
max_width=0
max_height=0
for monitor in "${monitor_array[@]}"; do
res=$(xrandr | grep -A1 "^$monitor connected" | tail -1 | awk '{print $1}')
width=$(echo $res | awk -Fx '{print $1}')
height=$(echo $res | awk -Fx '{print $2}')
if (( width > max_width )); then
max_width=$width
fi
if (( height > max_height )); then
max_height=$height
fi
done
echo -e "${CYAN}Highest resolution found: ${max_width}x${max_height}${RESET}"
# Scale all monitors to the maximum resolution
for monitor in "${monitor_array[@]}"; do
echo -e "${CYAN}Scaling $monitor to ${max_width}x${max_height}${RESET}"
execute_command "xrandr --output $monitor --scale-from ${max_width}x${max_height}"
done
echo -e "${GREEN}Scaling complete. All monitors are now scaled to ${max_width}x${max_height}.${RESET}"
}
# Call the scale_monitors function
scale_monitors

View File

@ -0,0 +1,37 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
# Function to set a monitor as primary
set_primary_monitor() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Set Primary Monitor${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose a monitor to set as primary:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the number of the monitor: " monitor_choice
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection.${RESET}"
return
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
if confirm_action "Set ${CYAN}$monitor_name${RESET} as the primary monitor?"; then
echo -e "${GREEN}Setting $monitor_name as primary monitor${RESET}"
execute_command "xrandr --output $monitor_name --primary"
echo -e "${GREEN}Monitor $monitor_name set as primary successfully.${RESET}"
else
echo -e "${RED}Action canceled.${RESET}"
fi
}
# Call the set_primary_monitor function
set_primary_monitor

View File

@ -0,0 +1,92 @@
#!/bin/bash
source ./utils/monitor-control/utility_functions.sh
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
# Function to set resolutions
set_resolutions() {
monitor_list=$(detect_connected_monitors)
IFS=$'\n' read -r -d '' -a monitor_array <<<"$monitor_list"
while true; do
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Monitor Configuration${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose a monitor to configure:${RESET}"
for i in "${!monitor_array[@]}"; do
echo -e "$((i + 1)). ${CYAN}${monitor_array[i]}${RESET}"
done
read -p "Enter the choice (or 'q' to quit): " monitor_choice
if [[ "$monitor_choice" == "q" ]]; then
echo -e "${RED}Exiting...${RESET}"
return
fi
if ! [[ "$monitor_choice" =~ ^[0-9]+$ ]] || (( monitor_choice < 1 )) || (( monitor_choice > ${#monitor_array[@]} )); then
echo -e "${RED}Invalid selection. Please try again.${RESET}"
read -p "Press [Enter] to continue..."
continue
fi
monitor_name="${monitor_array[monitor_choice - 1]}"
resolutions=$(get_unique_resolutions "$monitor_name")
# Create a temporary file with sorted resolutions and indices
temp_res_file=$(mktemp)
echo "$resolutions" | sort -nr | awk '{print NR " " $0}' > "$temp_res_file"
# Read the sorted resolutions into an associative array
declare -A resolution_map
while read -r index resolution; do
resolution_map[$index]="$resolution"
done < "$temp_res_file"
clear
echo -e "${BLUE}=========================================${RESET}"
echo -e "${BLUE} Resolution Configuration for ${CYAN}$monitor_name${RESET}"
echo -e "${BLUE}=========================================${RESET}"
echo -e "${YELLOW}Choose resolution for $monitor_name:${RESET}"
awk '{print $1 ". " $2}' "$temp_res_file"
while true; do
read -p "Enter the choice (or 'q' to quit): " resolution_choice
if [[ "$resolution_choice" == "q" ]]; then
echo -e "${RED}Exiting...${RESET}"
rm "$temp_res_file"
return
fi
if ! [[ "$resolution_choice" =~ ^[0-9]+$ ]] || (( resolution_choice < 1 )) || (( resolution_choice > ${#resolution_map[@]} )); then
echo -e "${RED}Invalid selection. Please try again.${RESET}"
continue
fi
# Map the index to the actual resolution
selected_resolution=${resolution_map[$resolution_choice]}
read -p "Set resolution for $monitor_name to $selected_resolution? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
echo -e "${GREEN}Setting resolution for $monitor_name to $selected_resolution${RESET}"
execute_command "xrandr --output $monitor_name --mode $selected_resolution"
break
else
echo -e "${RED}Action canceled. Please choose a different resolution.${RESET}"
fi
done
# Clean up the temporary file
rm "$temp_res_file"
done
}
set_resolutions

View File

@ -0,0 +1,36 @@
#!/bin/bash
# Function to execute xrandr commands and handle errors
execute_command() {
local command="$1"
echo "Executing: $command"
eval "$command" 2>&1 | tee /tmp/xrandr.log | tail -n 20
if [ $? -ne 0 ]; then
echo "An error occurred while executing the command. Check /tmp/xrandr.log for details."
fi
}
# Function to detect connected monitors
detect_connected_monitors() {
xrandr_output=$(xrandr)
echo "$xrandr_output" | grep " connected" | awk '{print $1}'
}
# Function to get resolutions for a monitor
get_unique_resolutions() {
local monitor="$1"
xrandr_output=$(xrandr)
echo "$xrandr_output" | grep -A 10 "$monitor connected" | grep -oP '\d+x\d+' | sort -u
}
# Function to prompt for confirmation
confirm_action() {
local action="$1"
echo "$action"
read -p "Are you sure? (y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
return 0
else
return 1
fi
}

View File

@ -0,0 +1,169 @@
@@ -0,0 +1,168 @@
#!/bin/bash
# Function to display colored text
colored_echo() {
local color=$1
local text=$2
case $color in
red) echo -e "\033[31m$text\033[0m" ;;
green) echo -e "\033[32m$text\033[0m" ;;
yellow) echo -e "\033[33m$text\033[0m" ;;
blue) echo -e "\033[34m$text\033[0m" ;;
*) echo "$text" ;;
esac
}
# Function to display the main menu
main_menu() {
while true; do
clear
colored_echo blue "WiFi Manager"
colored_echo blue "============"
echo "1. Turn WiFi On"
echo "2. Turn WiFi Off"
echo "3. Scan for WiFi networks"
echo "4. Connect to a WiFi network"
echo "5. Disconnect from a WiFi network"
echo "6. Remove a WiFi connection"
echo "0. Exit"
echo -n "Choose an option: "
read -e choice
case $choice in
1) wifi_on ;;
2) wifi_off ;;
3) scan_networks ;;
4) connect_network ;;
5) disconnect_network ;;
6) remove_network ;;
0) exit 0 ;;
*) colored_echo red "Invalid option. Please try again." ;;
esac
done
}
# Function to scan for WiFi networks
scan_networks() {
clear
colored_echo yellow "Scanning for WiFi networks..."
networks=$(nmcli -t -f SSID,BSSID,SIGNAL dev wifi list | head -n 10)
if [ -z "$networks" ]; then
colored_echo red "No networks found."
else
colored_echo green "Top 10 Networks found:"
echo "$networks" | sed 's/\\//g' | awk -F: '{printf("%d. SSID: %-25s \n", NR, $1)}'
fi
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to turn WiFi on
wifi_on() {
clear
colored_echo yellow "Turning WiFi on..."
nmcli radio wifi on && {
colored_echo green "WiFi is now turned on."
} || {
colored_echo red "Failed to turn on WiFi."
}
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to turn WiFi off
wifi_off() {
clear
colored_echo yellow "Turning WiFi off..."
nmcli radio wifi off && {
colored_echo green "WiFi is now turned off."
} || {
colored_echo red "Failed to turn off WiFi."
}
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to prompt for WiFi network selection
prompt_for_network() {
local action=$1
local prompt_msg=$2
local success_msg=$3
local failure_msg=$4
while true; do
clear
networks=$(nmcli -t -f SSID dev wifi list | head -n 10)
if [ -z "$networks" ]; then
colored_echo red "No networks available. Please scan for networks first."
echo "Press any key to return to the main menu..."
read -n 1
return
fi
# Display networks with numbers
IFS=$'\n' read -rd '' -a network_list <<<"$networks"
for i in "${!network_list[@]}"; do
ssid=$(echo "${network_list[$i]}" | awk -F: '{print $1}')
echo "$((i+1)). SSID: $ssid"
done
echo "0. Exit to main menu"
echo -n "$prompt_msg"
read -e choice
# Validate the choice
if [[ $choice =~ ^[0-9]+$ ]] && [ "$choice" -le "${#network_list[@]}" ] && [ "$choice" -gt 0 ]; then
network=${network_list[$((choice-1))]}
ssid=$(echo "$network" | awk -F: '{print $1}')
if [ "$action" == "connect" ]; then
echo -n "Enter password for SSID $ssid: "
read -s password
echo
nmcli dev wifi connect "$ssid" password "$password" && {
colored_echo green "$success_msg"
break
} || {
colored_echo red "$failure_msg"
}
elif [ "$action" == "disconnect" ]; then
nmcli connection down "$ssid" && {
colored_echo green "$success_msg"
break
} || {
colored_echo red "$failure_msg"
}
elif [ "$action" == "remove" ]; then
nmcli connection delete "$ssid" && {
colored_echo green "$success_msg"
break
} || {
colored_echo red "$failure_msg"
}
fi
elif [ "$choice" -eq 0 ]; then
return
else
colored_echo red "Invalid choice. Please try again."
fi
done
echo "Press any key to return to the main menu..."
read -n 1
}
# Function to connect to a WiFi network
connect_network() {
prompt_for_network "connect" "Enter the number of the network to connect: " "Connected to the network successfully." "Failed to connect to the network."
}
# Function to disconnect from a WiFi network
disconnect_network() {
prompt_for_network "disconnect" "Enter the number of the network to disconnect: " "Disconnected from the network successfully." "Failed to disconnect from the network."
}
# Function to remove a WiFi connection
remove_network() {
prompt_for_network "remove" "Enter the number of the network to remove: " "Network removed successfully." "Failed to remove the network."
}
# Initialize
main_menu

View File

@ -58,6 +58,49 @@ impl CustomList {
name: "root", name: "root",
command: Command::None, command: Command::None,
} => { } => {
ListNode {
name: "Applications Setup",
command: Command::None
} => {
ListNode {
name: "Alacritty",
command: Command::LocalFile("applications-setup/alacritty-setup.sh"),
},
ListNode {
name: "Bash Prompt",
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/mybash/main/setup.sh)\""),
},
ListNode {
name: "DWM-Titus",
command: Command::LocalFile("applications-setup/dwmtitus-setup.sh")
},
ListNode {
name: "Kitty",
command: Command::LocalFile("applications-setup/kitty-setup.sh")
},
ListNode {
name: "Neovim",
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/neovim/main/setup.sh)\""),
},
ListNode {
name: "Rofi",
command: Command::LocalFile("applications-setup/rofi-setup.sh"),
},
ListNode {
name: "ZSH Prompt",
command: Command::LocalFile("applications-setup/zsh-setup.sh"),
}
},
ListNode {
name: "Security",
command: Command::None
} => {
ListNode {
name: "Firewall Baselines (CTT)",
command: Command::LocalFile("security/firewall-baselines.sh"),
}
},
ListNode { ListNode {
name: "System Setup", name: "System Setup",
command: Command::None, command: Command::None,
@ -74,39 +117,71 @@ impl CustomList {
name: "Global Theme", name: "Global Theme",
command: Command::LocalFile("system-setup/3-global-theme.sh"), command: Command::LocalFile("system-setup/3-global-theme.sh"),
}, },
ListNode {
name: "Remove Snaps",
command: Command::LocalFile("system-setup/4-remove-snaps.sh"),
},
}, },
ListNode { ListNode {
name: "Security", name: "Utilities",
command: Command::None command: Command::None
} => { } => {
ListNode { ListNode {
name: "Firewall Baselines (CTT)", name: "Wifi Manager",
command: Command::LocalFile("security/firewall-baselines.sh"), command: Command::LocalFile("utils/wifi-control.sh"),
}
},
ListNode {
name: "Applications Setup",
command: Command::None
} => {
ListNode {
name: "Alacritty Setup",
command: Command::LocalFile("applications-setup/alacritty-setup.sh"),
}, },
ListNode { ListNode {
name: "Bash Prompt Setup", name: "Bluetooth Manager",
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/mybash/main/setup.sh)\""), command: Command::LocalFile("utils/bluetooth-control.sh"),
}, },
ListNode { ListNode {
name: "Kitty Setup", name: "MonitorControl(xorg)",
command: Command::LocalFile("applications-setup/kitty-setup.sh") command: Command::None,
}, } => {
ListNode { ListNode {
name: "Neovim Setup", name: "Set Resolution",
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/neovim/main/setup.sh)\""), command: Command::LocalFile("utils/monitor-control/set_resolutions.sh"),
}, },
ListNode { ListNode {
name: "Rofi Setup", name: "Duplicate Displays",
command: Command::LocalFile("applications-setup/rofi-setup.sh"), command: Command::LocalFile("utils/monitor-control/duplicate_displays.sh"),
},
ListNode {
name: "Extend Displays",
command: Command::LocalFile("utils/monitor-control/extend_displays.sh"),
},
ListNode {
name: "Auto Detect Displays",
command: Command::LocalFile("utils/monitor-control/auto_detect_displays.sh"),
},
ListNode {
name: "Enable Monitor",
command: Command::LocalFile("utils/monitor-control/enable_monitor.sh"),
},
ListNode {
name: "Disable Monitor",
command: Command::LocalFile("utils/monitor-control/disable_monitor.sh"),
},
ListNode {
name: "Set Primary Monitor",
command: Command::LocalFile("utils/monitor-control/set_primary_monitor.sh"),
},
ListNode {
name: "Change Orientation",
command: Command::LocalFile("utils/monitor-control/change_orientation.sh"),
},
ListNode {
name: "Manage Arrangement",
command: Command::LocalFile("utils/monitor-control/manage_arrangement.sh"),
},
ListNode {
name: "Scale Monitors",
command: Command::LocalFile("utils/monitor-control/scale_monitor.sh"),
},
ListNode {
name: "Reset Scaling",
command: Command::LocalFile("utils/monitor-control/reset_scaling.sh"),
},
}, },
}, },
ListNode { ListNode {
@ -259,10 +334,10 @@ impl CustomList {
// so the scroll does not happen in the main window as well // so the scroll does not happen in the main window as well
if self.preview_window_state.is_some() { if self.preview_window_state.is_some() {
self.scroll_preview_window_down(); self.scroll_preview_window_down();
return None; } else {
self.list_state.select_next();
} }
self.list_state.select_next();
None None
} }
KeyCode::Char('k') | KeyCode::Up => { KeyCode::Char('k') | KeyCode::Up => {
@ -270,10 +345,10 @@ impl CustomList {
// so the scroll does not happen in the main window as well // so the scroll does not happen in the main window as well
if self.preview_window_state.is_some() { if self.preview_window_state.is_some() {
self.scroll_preview_window_up(); self.scroll_preview_window_up();
return None; } else {
self.list_state.select_previous();
} }
self.list_state.select_previous();
None None
} }
// The 'p' key toggles the preview on and off // The 'p' key toggles the preview on and off

View File

@ -142,15 +142,6 @@ fn run<B: Backend>(terminal: &mut Terminal<B>, state: &AppState) -> io::Result<(
command_opt = None; command_opt = None;
} }
} else { } else {
if key.code == KeyCode::Char('q') {
return Ok(());
}
//Activate search mode if the forward slash key gets pressed
if key.code == KeyCode::Char('/') {
// Enter search mode
in_search_mode = true;
continue;
}
//Insert user input into the search bar //Insert user input into the search bar
if in_search_mode { if in_search_mode {
match key.code { match key.code {
@ -175,6 +166,18 @@ fn run<B: Backend>(terminal: &mut Terminal<B>, state: &AppState) -> io::Result<(
} }
} else if let Some(cmd) = custom_list.handle_key(key, state) { } else if let Some(cmd) = custom_list.handle_key(key, state) {
command_opt = Some(RunningCommand::new(cmd, state)); command_opt = Some(RunningCommand::new(cmd, state));
} else {
// Handle keys while not in search mode
match key.code {
// Exit the program
KeyCode::Char('q') => return Ok(()),
//Activate search mode if the forward slash key gets pressed
KeyCode::Char('/') => {
in_search_mode = true;
continue;
}
_ => {}
}
} }
} }
} }