diff --git a/README.md b/README.md
index 17e4980..ab3c524 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,29 @@
-# Proton-Community-Updater
-Script to download and manage Community Proton builds
+# Proton Community Updater
+**Script to download and manage Community Proton builds**
+
+This script is an easy way to download, extract and delete custom Proton Versions from different contributors.
+Currently, GloriousEggroll and TKG are implemented, but the list can easily be complemented - and if you want some other Builds to be added by default, just tell me! :)
+
+The script uses Zenity (if its installed) to display a nice GUI, but can be run in CLI-Mode as well, if Zenity is not found.
+
+## Dependencies
+
+- **bash** - obvioulsy
+- **coreutils** - also pretty obvious
+- **curl** - to download the release-lists and the selected versions
+- **xz** - to extract the tar.xz archives used by TKG
+- **zenity** - optional, for displaying the GUI
+
+## Installation:
+
+From Source:
+1. Download it!
+2. Run it!
+3. If you want, move *proton-community-updater-icon.png* to */usr/share/pixmaps/*
+
+For Arch Linux and derivatives: https://aur.archlinux.org/packages/proton-community-updater/
+
+## Contributors/recognition:
+- https://github.com/the-sane/lug-helper for the awesome zenity-"framework"
+- https://github.com/flubberding/ProtonUpdater for the initial inspiration and groundwork for downloading
+- https://github.com/richardtatum/sc-runner-updater for adding upon flubberdings single-version downloader
diff --git a/proton-community-updater-icon.png b/proton-community-updater-icon.png
new file mode 100644
index 0000000..9271ad6
Binary files /dev/null and b/proton-community-updater-icon.png differ
diff --git a/proton-community-updater.sh b/proton-community-updater.sh
new file mode 100755
index 0000000..2c9e0e1
--- /dev/null
+++ b/proton-community-updater.sh
@@ -0,0 +1,670 @@
+#!/usr/bin/env bash
+
+############################################################################
+# Proton Community Build download and management script
+############################################################################
+#
+#
+#
+#
+# made with <3
+# Author: https://github.com/Termuellinator
+#
+# Based on https://github.com/the-sane/lug-helper
+# and
+# https://github.com/richardtatum/sc-runner-updater
+
+############################################################################
+
+###################### Variables to be changed by user #####################
+# steam proton directory
+# may also be "$HOME/.steam/root/compatibilitytools.d" or "$HOME/.steam/compatibilitytools.d" depending on distro
+proton_dir="$HOME/.steam/steam/compatibilitytools.d/"
+#
+# URLs for downloading Proton builds
+# Elements in this array must be added in quoted pairs of: "description" "url"
+# The first string in the pair is expected to contain the proton description
+# The second is expected to contain the github api releases url
+# ie. "GloriousEggroll" "https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases"
+proton_sources=(
+ "GloriousEggroll" "https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases"
+ "TKG" "https://api.github.com/repos/Frogging-Family/wine-tkg-git/releases"
+)
+# Set a maximum number of proton versions to display from each url
+max_versions=20
+
+############################################################################
+
+# Check if script is run as root
+if [ "$(id -u)" = 0 ]; then
+echo "This script is not supposed to be run as root!"
+exit 1
+fi
+
+# Check for dependencies
+if [ ! -x "$(command -v curl)" ]; then
+# Print to stderr and also try warning the user through notify-send
+ printf "proton-community-updater.sh: The required package 'curl' was not found on this system.\n" 1>&2
+ notify-send "proton-community-updater" "The required package 'curl' was not found on this system.\n" --icon=dialog-warning
+ exit 1
+fi
+if [ ! -x "$(command -v mktemp)" ] || [ ! -x "$(command -v basename)" ]; then
+ # Print to stderr and also try warning the user through notify-send
+ printf "proton-community-updater.sh: One or more required packages were not found on this system.\nPlease check that the following packages are installed:\n- mktemp (part of gnu coreutils)\n- basename (part of gnu coreutils)\n" 1>&2
+ notify-send "proton-community-updater" "One or more required packages were not found on this system.\nPlease check that the following packages are installed:\n- mktemp (part of gnu coreutils)\n- basename (part of gnu coreutils)\n" --icon=dialog-warning
+ exit 1
+fi
+
+# Temporary directory
+tmp_dir="$(mktemp -d --suffix=".proton-community-updater")"
+trap 'rm -r "$tmp_dir"' EXIT
+
+############################################################################
+
+# Pixels to add for each Zenity menu option
+# used to dynamically determine the height of menus
+menu_option_height="25"
+
+# Use logo installed by a packaged version of this script if available
+# Otherwise, default to the logo in the same directory
+if [ -f "/usr/share/pixmaps/proton-community-updater-icon.png" ]; then
+ pcu_logo="/usr/share/pixmaps/proton-community-updater-icon.png"
+elif [ -f "proton-community-updater-icon.png" ]; then
+ pcu_logo="proton-community-updater-icon.png"
+else
+ pcu_logo="info"
+fi
+
+############################################################################
+############################################################################
+
+
+# Echo a formatted debug message to the terminal and optionally exit
+# Accepts either "continue" or "exit" as the first argument
+# followed by the string to be echoed
+debug_print() {
+ # This function expects two string arguments
+ if [ "$#" -lt 2 ]; then
+ printf "\nScript error: The debug_print function expects two arguments. Aborting.\n"
+ read -n 1 -s -p "Press any key..."
+ exit 0
+ fi
+
+ # Echo the provided string and, optionally, exit the script
+ case "$1" in
+ "continue")
+ printf "\n$2\n"
+ ;;
+ "exit")
+ # Write an error to stderr and exit
+ printf "proton-community-updater.sh: $2\n" 1>&2
+ read -n 1 -s -p "Press any key..."
+ exit 1
+ ;;
+ *)
+ printf "proton-community-updater.sh: Unknown argument provided to debug_print function. Aborting.\n" 1>&2
+ read -n 1 -s -p "Press any key..."
+ exit 0
+ ;;
+ esac
+}
+
+# Display a message to the user.
+# Expects the first argument to indicate the message type, followed by
+# a string of arguments that will be passed to zenity or echoed to the user.
+#
+# To call this function, use the following format: message [type] "[string]"
+# See the message types below for instructions on formatting the string.
+message() {
+ # Sanity check
+ if [ "$#" -lt 2 ]; then
+ debug_print exit "Script error: The message function expects two arguments. Aborting."
+ fi
+
+ # Use zenity messages if available
+ if [ "$use_zenity" -eq 1 ]; then
+ case "$1" in
+ "info")
+ # info message
+ # call format: message info "text to display"
+ margs=("--info" "--window-icon=$pcu_logo" "--no-wrap" "--text=")
+ ;;
+ "warning")
+ # warning message
+ # call format: message warning "text to display"
+ margs=("--warning" "--window-icon=$pcu_logo" "--text=")
+ ;;
+ "question")
+ # question
+ # call format: if message question "question to ask?"; then...
+ margs=("--question" "--window-icon=$pcu_logo" "--text=")
+ ;;
+ *)
+ debug_print exit "Script Error: Invalid message type passed to the message function. Aborting."
+ ;;
+ esac
+
+ # Display the message
+ shift 1 # drop the first argument and shift the remaining up one
+ zenity "${margs[@]}""$@" --width="400" --title="Proton Community Updater" 2>/dev/null
+ else
+ # Fall back to text-based messages when zenity is not available
+ case "$1" in
+ "info")
+ # info message
+ # call format: message info "text to display"
+ clear
+ printf "\n$2\n\n"
+ read -n 1 -s -p "Press any key..."
+ ;;
+ "warning")
+ # warning message
+ # call format: message warning "text to display"
+ clear
+ printf "\n$2\n\n"
+ read -n 1 -s -p "Press any key..."
+ return 0
+ ;;
+ "question")
+ # question
+ # call format: if message question "question to ask?"; then...
+ clear
+ printf "$2\n"
+ while read -p "[y/n]: " yn; do
+ case "$yn" in
+ [Yy]*)
+ return 0
+ ;;
+ [Nn]*)
+ return 1
+ ;;
+ *)
+ printf "Please type 'y' or 'n'\n"
+ ;;
+ esac
+ done
+ ;;
+ *)
+ debug_print exit "Script Error: Invalid message type passed to the message function. Aborting."
+ ;;
+ esac
+ fi
+}
+
+# Display a menu to the user.
+# Uses Zenity for a gui menu with a fallback to plain old text.
+#
+# How to call this function:
+#
+# Requires two arrays to be set: "menu_options" and "menu_actions"
+# two string variables: "menu_text_zenity" and "menu_text_terminal"
+# and one integer variable: "menu_height".
+#
+# - The array "menu_options" should contain the strings of each option.
+# - The array "menu_actions" should contain function names to be called.
+# - The strings "menu_text_zenity" and "menu_text_terminal" should contain
+# the menu description formatted for zenity and the terminal, respectively.
+# This text will be displayed above the menu options.
+# Zenity supports Pango Markup for text formatting.
+# - The integer "menu_height" specifies the height of the zenity menu.
+#
+# The final element in each array is expected to be a quit option.
+#
+# IMPORTANT: The indices of the elements in "menu_actions"
+# *MUST* correspond to the indeces in "menu_options".
+# In other words, it is expected that menu_actions[1] is the correct action
+# to be executed when menu_options[1] is selected, and so on for each element.
+#
+# See MAIN at the bottom of this script for an example of generating a menu.
+menu() {
+ # Sanity checks
+ if [ "${#menu_options[@]}" -eq 0 ]; then
+ debug_print exit "Script error: The array 'menu_options' was not set\nbefore calling the menu function. Aborting."
+ elif [ "${#menu_actions[@]}" -eq 0 ]; then
+ debug_print exit "Script error: The array 'menu_actions' was not set\nbefore calling the menu function. Aborting."
+ elif [ -z "$menu_text_zenity" ]; then
+ debug_print exit "Script error: The string 'menu_text_zenity' was not set\nbefore calling the menu function. Aborting."
+ elif [ -z "$menu_text_terminal" ]; then
+ debug_print exit "Script error: The string 'menu_text_terminal' was not set\nbefore calling the menu function. Aborting."
+ elif [ -z "$menu_height" ]; then
+ debug_print exit "Script error: The string 'menu_height' was not set\nbefore calling the menu function. Aborting."
+ fi
+
+ # Use Zenity if it is available
+ if [ "$use_zenity" -eq 1 ]; then
+ # Format the options array for Zenity by adding
+ # TRUE or FALSE to indicate default selections
+ # ie: "TRUE" "List item 1" "FALSE" "List item 2" "FALSE" "List item 3"
+ for (( i=0; i<"${#menu_options[@]}"-1; i++ )); do
+ if [ "$i" -eq 0 ]; then
+ # Select the first radio button by default
+ zen_options=("TRUE")
+ zen_options+=("${menu_options[i]}")
+ else
+ zen_options+=("FALSE")
+ zen_options+=("${menu_options[i]}")
+ fi
+ done
+
+ # Display the zenity radio button menu
+ choice="$(zenity --list --radiolist --width="480" --height="$menu_height" --text="$menu_text_zenity" --title="Proton Community Updater" --hide-header --window-icon=$pcu_logo --column="" --column="Option" "${zen_options[@]}" 2>/dev/null)"
+
+ # Loop through the options array to match the chosen option
+ matched="false"
+ for (( i=0; i<"${#menu_options[@]}"; i++ )); do
+ if [ "$choice" = "${menu_options[i]}" ]; then
+ # Execute the corresponding action
+ ${menu_actions[i]}
+ matched="true"
+ break
+ fi
+ done
+
+ # If no match was found, the user clicked cancel
+ if [ "$matched" = "false" ]; then
+ # Execute the last option in the actions array
+ "${menu_actions[${#menu_actions[@]}-1]}"
+ fi
+ else
+ # Use a text menu if Zenity is not available
+ clear
+ printf "\n$menu_text_terminal\n\n"
+
+ PS3="Enter selection number: "
+ select choice in "${menu_options[@]}"
+ do
+ # Loop through the options array to match the chosen option
+ matched="false"
+ for (( i=0; i<"${#menu_options[@]}"; i++ )); do
+ if [ "$choice" = "${menu_options[i]}" ]; then
+ # Execute the corresponding action
+ printf "\n\n"
+ ${menu_actions[i]}
+ matched="true"
+ break
+ fi
+ done
+
+ # Check if we're done looping the menu
+ if [ "$matched" = "true" ]; then
+ # Match was found and actioned, so exit the menu
+ break
+ else
+ # If no match was found, the user entered an invalid option
+ printf "\nInvalid selection.\n"
+ continue
+ fi
+ done
+ fi
+}
+
+# Called when the user clicks cancel on a looping menu
+# Causes a return to the main menu
+menu_loop_done() {
+ looping_menu="false"
+}
+
+
+
+#------------------------- begin Proton Builds functions ----------------------------#
+
+# Restart lutris
+steam_restart() {
+ if [ "$steam_needs_restart" = "true" ] && [ "$(pgrep steam)" ]; then
+ if message question "Steam must be restarted to detect changes in installed Proton versions.\nWould you like this Helper to restart it for you?"; then
+ debug_print continue "Restarting Steam..."
+ pkill -SIGTERM steam && nohup steam /dev/null &
+ fi
+ fi
+ steam_needs_restart="false"
+}
+
+# Delete the selected proton
+proton_delete() {
+ # This function expects an index number for the array
+ # installed_proton to be passed in as an argument
+ if [ -z "$1" ]; then
+ debug_print exit "Script error: The proton_delete function expects an argument. Aborting."
+ fi
+
+ proton_to_delete="$1"
+ if message question "Are you sure you want to delete the following Proton Build?\n\n${installed_proton[$proton_to_delete]}"; then
+ rm -rf "${installed_proton[$proton_to_delete]}"
+ debug_print continue "Deleted ${installed_proton[$proton_to_delete]}"
+ steam_needs_restart="true"
+ fi
+}
+
+# List installed Proton Builds for deletion
+proton_select_delete() {
+ # Configure the menu
+ menu_text_zenity="Select the Proton build you want to remove:"
+ menu_text_terminal="Select the Proton build you want to remove:"
+ menu_text_height="65"
+ goback="Return to the Proton management menu"
+ unset installed_proton
+ unset menu_options
+ unset menu_actions
+
+ # Create an array containing all directories in the proton_dir
+ for proton_list in "$proton_dir"/*; do
+ if [ -d "$proton_list" ]; then
+ installed_proton+=("$proton_list")
+ fi
+ done
+
+ # Create menu options for the installed proton builds
+ for (( i=0; i<"${#installed_proton[@]}"; i++ )); do
+ menu_options+=("$(basename "${installed_proton[i]}")")
+ menu_actions+=("proton_delete $i")
+ done
+
+ # Complete the menu by adding the option to go back to the previous menu
+ menu_options+=("$goback")
+ menu_actions+=(":") # no-op
+
+ # Calculate the total height the menu should be
+ menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height))"
+ if [ "$menu_height" -gt "400" ]; then
+ menu_height="400"
+ fi
+
+ # Call the menu function. It will use the options as configured above
+ menu
+}
+
+# Download and install the selected proton build
+# Note: The variables proton_versions, contributor_url, and proton_url_type
+# are expected to be set before calling this function
+proton_install() {
+ # This function expects an index number for the array
+ # proton_versions to be passed in as an argument
+ if [ -z "$1" ]; then
+ debug_print exit "Script error: The proton_install function expects a numerical argument. Aborting."
+ fi
+
+ # Get the proton build filename including file extension
+ proton_file="${proton_versions[$1]}"
+
+ # Get the selected proton build name minus the file extension
+ # To add new file extensions, handle them here and in
+ # the proton_select_install function below
+ case "$proton_file" in
+ *.tar.gz)
+ proton_name="$(basename "$proton_file" .tar.gz)"
+ ;;
+ *.tgz)
+ proton_name="$(basename "$proton_file" .tgz)"
+ ;;
+ *.tar.xz)
+ proton_name="$(basename "$proton_file" .tar.xz)"
+ ;;
+ *)
+ debug_print exit "Unknown archive filetype in proton_install function. Aborting."
+ ;;
+ esac
+
+ # Get the selected proton build url
+ # To add new sources, handle them here and in the
+ # proton_select_install function below
+ if [ "$proton_url_type" = "github" ]; then
+ proton_dl_url="$(curl -s "$contributor_url" | grep "browser_download_url.*$proton_file" | cut -d \" -f4)"
+ else
+ debug_print exit "Script error: Unknown api/url format in proton_sources array. Aborting."
+ fi
+
+ # Sanity check
+ if [ -z "$proton_dl_url" ]; then
+ message warning "Could not find the requested Proton build. The source API may be down or rate limited."
+ return 1
+ fi
+
+ # Download the proton build to the tmp directory
+ debug_print continue "Downloading $proton_dl_url into $tmp_dir/$proton_file..."
+ if [ "$use_zenity" -eq 1 ]; then
+ # Format the curl progress bar for zenity
+ mkfifo "$tmp_dir/protonpipe"
+ cd "$tmp_dir" && curl -#LO "$proton_dl_url" > "$tmp_dir/protonpipe" 2>&1 & curlpid="$!"
+ stdbuf -oL tr '\r' '\n' < "$tmp_dir/protonpipe" | \
+ grep --line-buffered -ve "100" | grep --line-buffered -o "[0-9]*\.[0-9]" | \
+ (
+ trap 'kill "$curlpid"' ERR
+ zenity --progress --auto-close --title="Proton Community Updater" --text="Downloading Proton build. This might take a moment.\n" 2>/dev/null
+ )
+
+ if [ "$?" -eq 1 ]; then
+ # User clicked cancel
+ debug_print continue "Download aborted. Removing $tmp_dir/$proton_file..."
+ rm "$tmp_dir/$proton_file"
+ rm "$tmp_dir/protonpipe"
+ return 1
+ fi
+ rm "$tmp_dir/protonpipe"
+ else
+ # Standard curl progress bar
+ (cd "$tmp_dir" && curl -LO "$proton_dl_url")
+ fi
+
+ # Sanity check
+ if [ ! -f "$tmp_dir/$proton_file" ]; then
+ debug_print exit "Script error: The requested proton build file was not downloaded. Aborting"
+ fi
+
+ # Check if the archive has /files/ folder at top level and deciding wheather or not to create a subfolder
+ if tar tf "$tmp_dir/$proton_file" | grep -m 1 -E "^files" > /dev/null; then
+ # Create subfolder by the name of $proton_name and extract archive there
+ debug_print continue "Installing Proton into $proton_dir/$proton_name..."
+ if [ "$use_zenity" -eq 1 ]; then
+ # Use Zenity progress bar
+ mkdir -p "$proton_dir/$proton_name" && tar -xf "$tmp_dir/$proton_file" -C "$proton_dir/$proton_name" | \
+ zenity --progress --pulsate --no-cancel --auto-close --title="Proton Community Updater" --text="Installing Proton build...\n" 2>/dev/null
+ else
+ mkdir -p "$proton_dir/$proton_name" && tar -xf "$tmp_dir/$proton_file" -C "$proton_dir/$proton_name"
+ fi
+ steam_needs_restart="true"
+ else
+ # Extract archive without a subfolder as archive seems to contain subfolder already
+ debug_print continue "Installing Proton into $proton_dir..."
+ if [ "$use_zenity" -eq 1 ]; then
+ # Use Zenity progress bar
+ mkdir -p "$proton_dir" && tar -xf "$tmp_dir/$proton_file" -C "$proton_dir" | \
+ zenity --progress --pulsate --no-cancel --auto-close --title="Proton Community Updater" --text="Installing Proton build...\n" 2>/dev/null
+ else
+ mkdir -p "$proton_dir" && tar -xf "$tmp_dir/$proton_file" -C "$proton_dir"
+ fi
+ steam_needs_restart="true"
+ fi
+
+ # Cleanup tmp download
+ debug_print continue "Removing $tmp_dir/$proton_file..."
+ rm "$tmp_dir/$proton_file"
+}
+
+# List available Proton builds for download
+proton_select_install() {
+ # This function expects an element number for the array
+ # proton_sources to be passed in as an argument
+ if [ -z "$1" ]; then
+ debug_print exit "Script error: The proton_select_install function expects a numerical argument. Aborting."
+ fi
+
+ # Store the url from the selected contributor
+ contributor_url="${proton_sources[$1+1]}"
+
+ # Check the provided contributor url to make sure we know how to handle it
+ # To add new sources, add them here and handle in the if statement
+ # just below and the proton_install function above
+ case "$contributor_url" in
+ https://api.github.com*)
+ proton_url_type="github"
+ ;;
+ *)
+ debug_print exit "Script error: Unknown api/url format in proton_sources array. Aborting."
+ ;;
+ esac
+
+ # Fetch a list of proton versions from the selected contributor
+ # To add new sources, handle them here, in the if statement
+ # just above, and the proton_install function above
+ if [ "$proton_url_type" = "github" ]; then
+ proton_versions=($(curl -s "$contributor_url" | awk '/browser_download_url/ {print $2}' | xargs basename -a))
+ else
+ debug_print exit "Script error: Unknown api/url format in proton_sources array. Aborting."
+ fi
+
+ # Sanity check
+ if [ "${#proton_versions[@]}" -eq 0 ]; then
+ message warning "No proton versions were found. The source API may be down or rate limited."
+ return 1
+ fi
+
+ # Configure the menu
+ menu_text_zenity="Select the Proton build you want to install:"
+ menu_text_terminal="Select the Proton build you want to install:"
+ menu_text_height="65"
+ goback="Return to the Proton management menu"
+ unset menu_options
+ unset menu_actions
+
+ # Iterate through the versions, check if they are installed,
+ # and add them to the menu options
+ # To add new file extensions, handle them here and in
+ # the proton_install function above
+ for (( i=0; i<"$max_versions" && i<"${#proton_versions[@]}"; i++ )); do
+ # Get the proton name minus the file extension
+ case "${proton_versions[i]}" in
+ *.tar.gz)
+ proton_name="$(basename "${proton_versions[i]}" .tar.gz)"
+ ;;
+ *.tgz)
+ proton_name="$(basename "${proton_versions[i]}" .tgz)"
+ ;;
+ *.tar.xz)
+ proton_name="$(basename "${proton_versions[i]}" .tar.xz)"
+ ;;
+ *)
+ proton_name="skip"
+ ;;
+ esac
+
+ # Add the proton names to the menu
+ if [ $proton_name = "skip" ]; then
+ continue
+ elif [ -d "$proton_dir/$proton_name" ]; then
+ menu_options+=("$proton_name [installed]")
+ else
+ menu_options+=("$proton_name")
+ fi
+ menu_actions+=("proton_install $i")
+ done
+
+ # Complete the menu by adding the option to go back to the previous menu
+ menu_options+=("$goback")
+ menu_actions+=(":") # no-op
+
+ # Calculate the total height the menu should be
+ menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height))"
+ if [ "$menu_height" -gt "400" ]; then
+ menu_height="400"
+ fi
+
+ # Call the menu function. It will use the options as configured above
+ menu
+}
+
+# Manage Proton Builds
+proton_manage() {
+ # Check if Lutris is installed
+ if [ ! -x "$(command -v steam)" ]; then
+ message info "Steam does not appear to be installed."
+ return 0
+ fi
+ if [ ! -d "$proton_dir" ]; then
+ message info "Proton directory not found. Unable to continue.\n\n$proton_dir"
+ return 0
+ fi
+
+ # The proton management menu will loop until the user cancels
+ looping_menu="true"
+ while [ "$looping_menu" = "true" ]; do
+ # Configure the menu
+ menu_text_zenity="Manage Your Proton Builds\n\nThe Proton Builds listed below are custom builds not affiliated with Valve\n\nYou may choose from the following options:"
+ menu_text_terminal="Manage Your Proton Builds\n\nThe Proton Builds listed below are custom builds not affiliated with Valve\nYou may choose from the following options:"
+ menu_text_height="140"
+
+ # Configure the menu options
+ delete="Remove an installed Proton build"
+ back="Return to the main menu"
+ unset menu_options
+ unset menu_actions
+
+ # Loop through the proton_sources array and create a menu item
+ # for each one. Even numbered elements will contain the proton build name
+ for (( i=0; i<"${#proton_sources[@]}"; i=i+2 )); do
+ # Set the options to be displayed in the menu
+ menu_options+=("Install a Proton build from ${proton_sources[i]}")
+ # Set the corresponding functions to be called for each of the options
+ menu_actions+=("proton_select_install $i")
+ done
+
+ # Complete the menu by adding options to remove an installed proton build
+ # or go back to the previous menu
+ menu_options+=("$delete" "$back")
+ menu_actions+=("proton_select_delete" "menu_loop_done")
+
+ # Calculate the total height the menu should be
+ menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height))"
+
+ # Call the menu function. It will use the options as configured above
+ menu
+ done
+
+ # Check if steam needs to be restarted after making changes
+ steam_restart
+}
+
+#-------------------------- end Proton builds functions -----------------------------#
+
+
+quit() {
+ exit 0
+}
+
+
+############################################################################
+# MAIN
+############################################################################
+
+# Check if Zenity is available
+use_zenity=0
+if [ -x "$(command -v zenity)" ]; then
+ use_zenity=1
+fi
+
+# Set some defaults
+steam_needs_restart="false"
+
+
+# Loop the main menu until the user selects quit
+while true; do
+ # Configure the menu
+ menu_text_zenity="Welcome, fellow Penguin, to the Proton Community Updater!\n\nThis Helper is designed to help manage custom Proton builds\n\nYou may choose from the following options:"
+ menu_text_terminal="Welcome, fellow Penguin, to the Proton Community Updater!\n\nThis Helper is designed to help manage custom Proton builds\nYou may choose from the following options:"
+ menu_text_height="140"
+
+ # Configure the menu options
+ proton_msg="Download or delete custom Proton builds"
+ restart_msg="Restart Steam"
+ quit_msg="Quit"
+
+ # Set the options to be displayed in the menu
+ menu_options=("$proton_msg" "$restart_msg" "$quit_msg")
+ # Set the corresponding functions to be called for each of the options
+ menu_actions=("proton_manage" "steam-restart" "quit")
+
+ # Calculate the total height the menu should be
+ menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height))"
+
+ # Call the menu function. It will use the options as configured above
+ menu
+done