#!/data/data/com.termux/files/usr/bin/bash
#
# Termux Desktop
# A simple script to easily install supported desktop environments and
# window managers, along with other essential configurations and tools.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Author : @sabamdarif
# License : GPL-v3
# Description: This script automates the installation of various desktop environments and window managers
# Repository : https://github.com/sabamdarif/termux-desktop
#########################################################################
#
# Call First
#
#########################################################################
# shellcheck disable=SC2154
R="$(printf '\033[1;31m')"
G="$(printf '\033[1;32m')"
Y="$(printf '\033[1;33m')"
B="$(printf '\033[1;34m')"
C="$(printf '\033[1;36m')"
NC="$(printf '\033[0m')"
BOLD="$(printf '\033[1m')"
cd "$HOME" || exit 1
############### Define basic initial values ######################
TERMUX_DESKTOP_PATH="/data/data/com.termux/files/usr/etc/termux-desktop"
CONFIG_FILE="$TERMUX_DESKTOP_PATH/configuration.conf"
LOG_FILE="/data/data/com.termux/files/home/termux-desktop.log"
CALL_FROM_CHANGE_DISTRO=false
CALL_FROM_CHANGE_STYLE=false
IS_TERMUX_API_INSTALLED=false
LITE_MODE="${LITE,,}"
##################################################################
# create detailed log output
function debug_msg() {
local debug_message="[DEBUG] running: $BASH_COMMAND"
echo "$debug_message"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $debug_message" >>"$LOG_FILE"
}
function banner() {
clear
printf "%s############################################################\n" "$C"
printf "%s# #\n" "$C"
printf "%s# ▀█▀ █▀▀ █▀█ █▀▄▀█ █ █ ▀▄▀ █▀▄ █▀▀ █▀ █▄▀ ▀█▀ █▀█ █▀█ #\n" "$C"
printf "%s# █ ██▄ █▀▄ █ █ █▄█ █ █ █▄▀ ██▄ ▄█ █ █ █ █▄█ █▀▀ #\n" "$C"
printf "%s# #\n" "$C"
printf "%s######################### Termux Gui #######################%s\n" "$C" "$NC"
echo " "
}
# check if the script is running on termux or not
function check_termux() {
if [[ -z "$PREFIX" && "$PREFIX" != *"/com.termux/"* ]]; then
echo "${R}[${R}☓${R}]${R}${BOLD}Please run it inside termux${NC}"
exit 1
fi
}
#########################################################################
#
# Base Functions
#
#########################################################################
function print_log() {
local timestamp
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
local log_level="${2:-INFO}" # Default log level is INFO if not specified
local message="$1"
echo "[${timestamp}] ${log_level}: ${message}" >>"$LOG_FILE"
}
function log_warn() {
local timestamp
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local message="$1"
echo "[${timestamp}] WARN: ${message}" >>"$LOG_FILE"
}
function log_error() {
local timestamp
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local message="$1"
echo "[${timestamp}] ERROR: ${message}" >>"$LOG_FILE"
}
function log_debug() {
local timestamp
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local message="$1"
echo "[${timestamp}] DEBUG: ${message}" >>"$LOG_FILE"
}
function print_success() {
local msg
msg="$1"
echo "${R}[${G}✓${R}]${G} $msg ${NC}"
log_debug "$msg"
}
function print_failed() {
local msg
msg="$1"
echo "${R}[${R}☓${R}]${R} $msg ${NC}"
log_debug "$msg"
}
function print_warn() {
local msg
msg="$1"
echo "${R}[${Y}!${R}]${Y} $msg ${NC}"
log_debug "$msg"
}
function print_msg() {
local msg
msg="$1"
echo "${R}[${C}-${R}]${G} $msg ${NC}"
log_debug "$msg"
}
function wait_for_keypress() {
read -n1 -s -r -p "${R}[${C}-${R}]${G} Press any key to continue, CTRL+c to cancel...${NC}"
echo
}
function check_and_create_directory() {
if [[ -n "$1" && ! -d "$1" ]]; then
mkdir -p "$1"
log_debug "$1"
fi
}
# first check then delete
function check_and_delete() {
local files_folders
for files_folders in "$@"; do
if [[ -e "$files_folders" ]]; then
rm -rf "$files_folders" >/dev/null 2>&1
log_debug "$files_folders"
fi
done
}
# first check then backup
function check_and_backup() {
log_debug "Starting backup for: $*"
# shellcheck disable=SC2206
local files_folders_list=($@)
local files_folders
local date_str
date_str=$(date +"%d-%m-%Y")
for files_folders in "${files_folders_list[@]}"; do
if [[ -e "$files_folders" ]]; then
local backup="${files_folders}-${date_str}.bak"
if [[ -e "$backup" ]]; then
print_msg "Backup $backup already exists"
else
print_msg "Backing up $files_folders"
mv "$files_folders" "$backup"
log_debug "$files_folders $backup"
fi
else
print_msg "Path $files_folders does not exist"
fi
done
}
function download_file() {
local dest
local url
local max_retries=5
local attempt=1
local successful_attempt=0
if [[ -z "$2" ]]; then
url="$1"
dest="$(basename "$url")"
else
dest="$1"
url="$2"
fi
if [[ -z "$url" ]]; then
print_failed "No URL provided!"
return 1
fi
while [[ $attempt -le $max_retries ]]; do
print_msg "Downloading $dest..."
if [[ ! -s "$dest" ]]; then
check_and_delete "$dest"
fi
if command -v wget &>/dev/null; then
wget --tries=5 --timeout=15 --retry-connrefused -O "$dest" "$url"
else
curl -# -L "$url" -o "$dest"
fi
if [[ -f "$dest" && -s "$dest" ]]; then
successful_attempt=$attempt
break
else
print_failed "Download failed. Retrying... ($attempt/$max_retries)"
fi
((attempt++))
done
if [[ -f "$dest" ]]; then
if [[ $successful_attempt -eq 1 ]]; then
print_success "File downloaded successfully."
else
print_success "File downloaded successfully on attempt $successful_attempt."
fi
return 0
fi
print_failed "Failed to download the file after $max_retries attempts. Exiting."
return 1
}
# find a backup file which end with a number pattern and restore it
function check_and_restore() {
log_debug "Starting restore for: $*"
# shellcheck disable=SC2206
local files_folders_list=($@)
local files_folders
for files_folders in "${files_folders_list[@]}"; do
local latest_backup
latest_backup=$(find "$(dirname "$files_folders")" -maxdepth 1 -name "$(basename "$files_folders")-[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9].bak" 2>/dev/null | sort | tail -n 1)
if [[ -z "$latest_backup" ]]; then
print_msg "No backup found for $files_folders"
continue
fi
if [[ -e "$files_folders" ]]; then
print_msg "File $files_folders already exists"
else
print_msg "Restoring $files_folders"
mv "$latest_backup" "$files_folders"
log_debug "$latest_backup $files_folders"
fi
done
}
function detact_package_manager() {
# shellcheck disable=SC1091
source "/data/data/com.termux/files/usr/bin/termux-setup-package-manager"
if [[ "$TERMUX_APP_PACKAGE_MANAGER" == "apt" ]]; then
PACKAGE_MANAGER="apt"
elif [[ "$TERMUX_APP_PACKAGE_MANAGER" == "pacman" ]]; then
PACKAGE_MANAGER="pacman"
else
print_failed "${C} Could not detact your package manager, Switching To ${C}pkg ${NC}"
fi
log_debug "$PACKAGE_MANAGER"
}
# will check if the package is already installed or not, if it installed then reinstall and print success/failed message
function package_install_and_check {
log_debug "Starting package installation for: $*"
# shellcheck disable=SC2206
packs_list=($@)
# pacman part
if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
for package_name in "${packs_list[@]}"; do
if [[ "$package_name" == *"*"* ]]; then
log_debug "Processing wildcard pattern: $package_name"
packages=$(pacman -Ssq | grep -E "^${package_name//\*/.*}$")
log_debug "matched packages: ${C}$packages"
for package in $packages; do
retry_count=0
max_retries=5
install_success=false
while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
retry_count=$((retry_count + 1))
check_and_delete "$PREFIX/var/lib/pacman/db.lck"
print_msg "Installing Package : ${C}$package"
pacman -S --noconfirm "$package"
if pacman -Qi "$package" >/dev/null 2>&1; then
print_success "Successfully install package: ${C}$package"
install_success=true
else
print_warn "Failed to install package: ${C}${package}. ${Y}Trying again... ($retry_count)"
fi
done
done
else
retry_count=0
max_retries=5
install_success=false
while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
retry_count=$((retry_count + 1))
check_and_delete "$PREFIX/var/lib/pacman/db.lck"
print_msg "Installing Package : ${C}$package_name"
pacman -S --noconfirm "$package_name"
if pacman -Qi "$package_name" >/dev/null 2>&1; then
print_success "Successfully install package: ${C}$package_name"
install_success=true
else
print_warn "Failed to install package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
fi
done
fi
done
else
#apt part
for package_name in "${packs_list[@]}"; do
if [[ "$package_name" == *"*"* ]]; then
log_debug "Processing wildcard pattern: $package_name"
packages=$(apt-cache pkgnames | grep -E "^${package_name//\*/.*}$" | sort -u)
log_debug "matched packages: $packages"
for package in $packages; do
retry_count=0
max_retries=5
install_success=false
while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
retry_count=$((retry_count + 1))
print_msg "Installing package: ${C}$package"
apt install "$package" -y
if dpkg -s "$package" >/dev/null 2>&1; then
print_success "Successfully install package: ${C}$package"
install_success=true
else
print_warn "Failed to install package: ${C}${package}. ${Y}Trying again... ($retry_count)"
# Only run recovery commands on failure
dpkg --configure -a
apt --fix-broken install -y
apt install --fix-missing -y
fi
done
done
else
retry_count=0
max_retries=5
install_success=false
while [[ "$retry_count" -lt "$max_retries" && "$install_success" == false ]]; do
retry_count=$((retry_count + 1))
print_msg "Installing package: ${C}$package_name"
apt install "$package_name" -y
if dpkg -s "$package_name" >/dev/null 2>&1; then
print_success "Successfully install package: ${C}$package_name"
install_success=true
else
print_warn "Failed to install package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
# Only run recovery commands on failure
dpkg --configure -a
apt --fix-broken install -y
apt install --fix-missing -y
fi
done
fi
done
fi
}
# will check the package is installed or not then remove it
function package_check_and_remove() {
log_debug "Starting package removal for: $*"
local packs_list
# shellcheck disable=SC2206
packs_list=($@)
if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
for package_name in "${packs_list[@]}"; do
if [[ "$package_name" == *"*"* ]]; then
log_debug "Processing wildcard pattern: $package_name"
local packages
packages=$(pacman -Qsq | grep -E "^${package_name//\*/.*}$")
if [[ -z "$packages" ]]; then
print_success "No installed packages found matching: ${C}$package_name"
continue
fi
log_debug "matched packages: $packages"
for package in $packages; do
local retry_count=0
local max_retries=5
local remove_success=false
while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
retry_count=$((retry_count + 1))
check_and_delete "$PREFIX/var/lib/pacman/db.lck"
print_msg "Removing Package : ${C}$package"
pacman -Rnds --noconfirm "$package"
if ! pacman -Qi "$package" >/dev/null 2>&1; then
print_success "Successfully removed package: ${C}$package"
remove_success=true
else
print_warn "Failed to remove package: ${C}${package}. ${Y}Trying again...($retry_count)"
fi
done
done
else
if pacman -Qi "$package_name" >/dev/null 2>&1; then
local retry_count=0
local max_retries=5
local remove_success=false
while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
retry_count=$((retry_count + 1))
check_and_delete "$PREFIX/var/lib/pacman/db.lck"
print_msg "Removing Package : ${C}$package_name"
pacman -Rnds --noconfirm "$package_name"
if ! pacman -Qi "$package_name" >/dev/null 2>&1; then
print_success "Successfully removed package: ${C}$package_name"
remove_success=true
else
print_warn "Failed to remove package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
fi
done
else
print_success "Package ${C}$package_name${G} is not installed.${NC}"
fi
fi
done
else
for package_name in "${packs_list[@]}"; do
if [[ "$package_name" == *"*"* ]]; then
log_debug "Processing wildcard pattern: $package_name"
local packages
packages=$(dpkg-query -W -f='${binary:Package}\n' "${package_name}" 2>/dev/null | grep -v ' ')
if [[ -z "$packages" ]]; then
print_success "No installed packages found matching: ${C}$package_name"
continue
fi
log_debug "matched packages: $packages"
for package in $packages; do
local retry_count=0
local max_retries=5
local remove_success=false
while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
retry_count=$((retry_count + 1))
print_msg "Removing package: ${C}$package"
dpkg --configure -a >/dev/null
apt autoremove "$package" -y
if ! dpkg -s "$package" >/dev/null 2>&1; then
print_success "Successfully removed package: ${C}$package"
remove_success=true
else
print_warn "Failed to remove package: ${C}${package}. ${Y}Trying again...($retry_count)"
fi
done
done
else
if dpkg -s "$package_name" >/dev/null 2>&1; then
local retry_count=0
local max_retries=5
local remove_success=false
while [[ "$retry_count" -lt "$max_retries" && "$remove_success" == false ]]; do
retry_count=$((retry_count + 1))
print_msg "Removing package: ${C}$package_name"
dpkg --configure -a >/dev/null
apt autoremove "$package_name" -y
if ! dpkg -s "$package_name" >/dev/null 2>&1; then
print_success "Successfully removed package: ${C}$package_name"
remove_success=true
else
print_warn "Failed to remove package: ${C}${package_name}. ${Y}Trying again... ($retry_count)"
fi
done
else
print_success "Package ${C}$package_name${G} is not installed.${NC}"
fi
fi
done
fi
}
function get_file_name_number() {
current_file=$(basename "$0")
folder_name="${current_file%.sh}"
theme_number=$(echo "$folder_name" | grep -oE '[1-9][0-9]*')
log_debug "$theme_number"
}
function extract_archive() {
local archive="$1"
if [[ ! -f "$archive" ]]; then
print_failed "$archive doesn't exist"
fi
case "$archive" in
*.tar.gz | *.tgz)
print_success "Extracting ${C}$archive"
tar xzvf "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.tar.xz)
print_success "Extracting ${C}$archive"
tar xJvf "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.tar.bz2 | *.tbz2)
print_success "Extracting ${C}$archive"
tar xjvf "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.tar)
print_success "Extracting ${C}$archive"
tar xvf "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.bz2)
print_success "Extracting ${C}$archive"
bunzip2 -v "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.gz)
print_success "Extracting ${C}$archive${NC}"
gunzip -v "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.7z)
print_success "Extracting ${C}$archive"
7z x "$archive" -y || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.zip)
print_success "Extracting ${C}$archive"
unzip "${archive}" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*.rar)
print_success "Extracting ${C}$archive"
unrar x "$archive" || {
print_failed "Failed to extract ${C}$archive"
return 1
}
;;
*)
print_failed "Unsupported archive format: ${C}$archive"
return 1
;;
esac
print_success "Successfully extracted ${C}$archive"
log_debug "$archive"
}
# download a archive file and extract it in a folder
function download_and_extract() {
local url="$1"
local target_dir="$2"
local filename="${url##*/}"
if [[ -n "$target_dir" ]]; then
check_and_create_directory "$target_dir"
cd "$target_dir" || return 1
fi
if download_file "$filename" "$url"; then
if [[ -f "$filename" ]]; then
echo
extract_archive "$filename"
check_and_delete "$filename"
fi
else
print_failed "Failed to download ${C}${filename}"
print_msg "${C}Please check your internet connection"
fi
log_debug "$url $target_dir $filename"
}
count_subfolders() {
local owner="$1"
local repo="$2"
local path="$3"
local branch="$4"
local response
response=$(curl -s "https://api.github.com/repos/$owner/$repo/contents/$path?ref=$branch")
# Use jq to extract directories and count them; if none found then set to 0
local subfolder_count
subfolder_count=$(echo "$response" | jq -r '[.[] | select(.type == "dir")] | length')
echo "${subfolder_count:-0}"
log_debug "$subfolder_count"
}
# create a yes / no confirmation prompt
function confirmation_y_or_n() {
while true; do
# prompt
read -r -p "${R}[${C}-${R}]${Y}${BOLD} $1 ${Y}(y/n) ${NC}" response
# apply default
response="${response:-y}"
# lowercase
response="${response,,}"
# reject spaces or slashes
if [[ "$response" =~ [[:space:]/] ]]; then
echo
print_failed "Invalid input: no spaces or slashes allowed. Enter only 'y' or 'n'."
echo
continue
fi
# normalize full words to single letters
if [[ "$response" =~ ^(yes|y)$ ]]; then
response="y"
elif [[ "$response" =~ ^(no|n)$ ]]; then
response="n"
else
echo
print_failed "Invalid input. Please enter 'y', 'yes', 'n', or 'no'."
echo
continue
fi
# store in the caller’s variable
eval "$2='$response'"
# handle it
case $response in
y)
echo
print_success "Continuing with answer: $response"
echo
sleep 0.2
break
;;
n)
echo
print_msg "${C}Skipping this step${NC}"
echo
sleep 0.2
break
;;
esac
done
log_debug "$1 $response"
}
# get the latest version from a github releases
# ex. latest_tag=$(get_latest_release "$repo_owner" "$repo_name")
function get_latest_release() {
local repo_owner="$1"
local repo_name="$2"
curl -s "https://api.github.com/repos/$repo_owner/$repo_name/releases/latest" |
grep '"tag_name":' |
sed -E 's/.*"([^"]+)".*/\1/'
}
function install_font_for_style() {
local style_number="$1"
print_msg "Installing Fonts..."
check_and_create_directory "$HOME/.fonts"
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/$de_name/look_${style_number}/font.tar.gz" "$HOME/.fonts"
fc-cache -f
cd "$HOME" || return 1
}
# Use:- select_an_option 8 1 variable_name
function select_an_option() {
local max_options=$1
local default_option=${2:-1}
local response_var=$3
local response
while true; do
read -r -p "${Y}select an option (Default ${default_option}): ${NC}" response
response=${response:-$default_option}
if [[ $response =~ ^[0-9]+$ ]] && ((response >= 1 && response <= max_options)); then
echo
print_success "Continuing with answer: $response"
sleep 0.2
eval "$response_var=$response"
break
else
echo
print_failed " Invalid input, Please enter a number between 1 and $max_options"
fi
done
}
function read_conf() {
if [[ ! -f "$CONFIG_FILE" ]]; then
print_failed " Configuration file $CONFIG_FILE not found"
exit 0
fi
# shellcheck disable=SC1090
source "$CONFIG_FILE"
print_success "Configuration variables loaded"
validate_required_vars
}
function print_to_config() {
local var_name="$1"
local var_value="${2:-${!var_name}}"
local IFS=$' \t\n'
if grep -q "^${var_name}=" "$CONFIG_FILE" 2>/dev/null; then
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$CONFIG_FILE"
else
echo "${var_name}=${var_value}" >>"$CONFIG_FILE"
fi
log_debug "$var_name $var_value"
}
function validate_required_vars() {
local required_vars=(
# Basic system variables
"HOME"
"PREFIX"
"TMPDIR"
"PACKAGE_MANAGER"
# Display and GUI variables
"display_number"
"gui_mode"
"de_name"
"de_startup"
"de_on_startup"
# Hardware acceleration variables
"enable_hw_acc"
# Configuration paths
"CONFIG_FILE"
"themes_folder"
"icons_folder"
# apps
"installed_browser"
"installed_ide"
"installed_media_player"
"installed_photo_editor"
"installed_wine"
# extra
"chosen_shell_name"
"terminal_utility_setup_answer"
"fm_tools"
# Distro
"distro_add_answer"
)
# If hardware acceleration is enabled, add required variables
if [[ "$enable_hw_acc" == "y" ]]; then
required_vars+=(
"GPU_NAME"
"exp_termux_vulkan_hw_answer"
"termux_hw_answer"
)
fi
# If a distro is enabled, add required variables
if [[ "$distro_add_answer" == "y" ]]; then
required_vars+=(
"selected_distro_type"
"selected_distro"
"pd_audio_config_answer"
"pd_useradd_answer"
)
fi
if [[ "$distro_add_answer" == "y" ]] && [[ "$pd_useradd_answer" == "y" ]]; then
required_vars+=(
"user_name"
)
fi
if [[ "$enable_hw_acc" == "y" ]] && [[ "$distro_add_answer" == "y" ]]; then
required_vars+=(
"pd_hw_answer"
)
fi
print_msg "Validating required configuration values..."
local missing_vars=()
for var in "${required_vars[@]}"; do
if [[ -z "${!var}" ]]; then
missing_vars+=("$var")
fi
done
if ((${#missing_vars[@]} > 0)); then
print_failed "The following required configuration values are not set:"
for var in "${missing_vars[@]}"; do
echo " - $var"
log_debug "$var"
exit 1
done
exit 1
fi
print_success "All required variables are set"
return 0
}
#########################################################################
#
# Ask Required Questions
#
#########################################################################
# check the avilable styles and create a list to type the corresponding number
# in the style readme file the name must use this'## number name :' pattern, like:- ## 1. Basic Style:
function questions_theme_select() {
local owner="sabamdarif"
local repo="termux-desktop"
local main_folder="setup-files/$de_name"
local branch="setup-files"
# Set default style value based on the desktop environment (DE)
case "$de_name" in
xfce | mate) default_selection="1" ;;
lxqt | openbox) default_selection="2" ;;
i3wm | dwm | bspwm | awesome | fluxbox) default_selection="0" ;;
*) default_selection="0" ;;
esac
# Get the number of available custom styles
subfolder_count_value=$(count_subfolders "$owner" "$repo" "$main_folder" "$branch" 2>/dev/null)
# If no custom styles are available, use stock style and skip interaction
if [[ "$subfolder_count_value" -eq 0 ]]; then
print_msg "No custom setup is available for $de_name"
log_debug "no:- $subfolder_count_value, No custom setup is available for $de_name"
print_msg "Continuing with style 0: Stock"
style_answer=0
style_name="Stock"
log_debug "$style_answer $subfolder_count_value"
return
fi
# If custom styles exist, fetch and display them
local styles_url="https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/docs/${de_name}_styles.md"
if curl --head --silent --fail "$styles_url" >/dev/null; then
print_msg "Downloading list of available styles..."
check_and_delete "${current_path}/styles.md"
download_file "${current_path}/styles.md" "$styles_url"
else
log_debug "No custom setup is available for $de_name"
print_msg "Continuing with style 0: Stock"
style_answer=0
style_name="Stock"
log_debug "$style_answer $subfolder_count_value"
return
fi
if [[ "$subfolder_count_value" -gt 0 ]]; then
banner
print_msg "Check the $de_name styles preview"
echo
print_msg "From Here:- ${B}https://github.com/sabamdarif/termux-desktop/blob/main/docs/${de_name}_styles.md"
echo
print_msg "Number of available custom styles for $de_name is: ${C}${subfolder_count_value}"
echo
print_msg "Available Styles Are:"
echo
grep -oP '## \d+\..+?(?=(\n## \d+\.|\Z))' "${current_path}/styles.md" | while read -r style; do
echo "${Y}${style#### }${NC}"
done
while true; do
echo
read -r -p "${R}[${C}-${R}]${Y} Type number of the style (Press Enter to select default): ${NC}" style_answer
style_answer="${style_answer:-$default_selection}"
if [[ "$style_answer" =~ ^[0-9]+$ ]] && [[ "$style_answer" -ge 0 ]] && [[ "$style_answer" -le "$subfolder_count_value" ]]; then
style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo
print_success "Continuing with style number ${C}$style_answer (Style: $style_name${NC})"
echo
break
else
echo
print_failed "The entered style number is incorrect"
echo
print_msg "${Y}Please enter a number between 0 and ${subfolder_count_value}"
echo
print_msg "Check the $de_name styles section in GitHub"
echo
print_msg "${B}https://github.com/sabamdarif/termux-desktop/blob/main/docs/${de_name}_styles.md"
echo
fi
done
check_and_delete "${current_path}/styles.md"
log_debug "$style_answer $subfolder_count_value"
fi
}
function ask_to_chose_de() {
# Setlect Desktop Environment
banner
print_msg "Importing desktop related data..."
local owner="sabamdarif"
local repo="termux-desktop"
local branch="setup-files"
# calculate availabe styles for all the desktop environments
local total_custom_xfce_setup
total_custom_xfce_setup=$(count_subfolders "$owner" "$repo" "setup-files/xfce" "$branch" 2>/dev/null)
local total_custom_lxqt_setup
total_custom_lxqt_setup=$(count_subfolders "$owner" "$repo" "setup-files/lxqt" "$branch" 2>/dev/null)
local total_custom_mate_setup
total_custom_mate_setup=$(count_subfolders "$owner" "$repo" "setup-files/mate" "$branch" 2>/dev/null)
local total_custom_gnome_setup
total_custom_gnome_setup=$(count_subfolders "$owner" "$repo" "setup-files/gnome" "$branch" 2>/dev/null)
local total_custom_cinnamon_setup
total_custom_cinnamon_setup=$(count_subfolders "$owner" "$repo" "setup-files/cinnamon" "$branch" 2>/dev/null)
# calculate availabe styles for all the window managers
local total_custom_openbox_setup
total_custom_openbox_setup=$(count_subfolders "$owner" "$repo" "setup-files/openbox" "$branch" 2>/dev/null)
local total_custom_i3wm_setup
total_custom_i3wm_setup=$(count_subfolders "$owner" "$repo" "setup-files/i3wm" "$branch" 2>/dev/null)
local total_custom_dwm_setup
total_custom_dwm_setup=$(count_subfolders "$owner" "$repo" "setup-files/dwm" "$branch" 2>/dev/null)
local total_custom_bspwm_setup
total_custom_bspwm_setup=$(count_subfolders "$owner" "$repo" "setup-files/bspwm" "$branch" 2>/dev/null)
local total_custom_awesome_setup
total_custom_awesome_setup=$(count_subfolders "$owner" "$repo" "setup-files/awesome" "$branch" 2>/dev/null)
local total_custom_fluxbox_setup
total_custom_fluxbox_setup=$(count_subfolders "$owner" "$repo" "setup-files/fluxbox" "$branch" 2>/dev/null)
local total_custom_icewm_setup
total_custom_icewm_setup=$(count_subfolders "$owner" "$repo" "setup-files/icewm" "$branch" 2>/dev/null)
banner
print_msg "Select Desktop Environment"
echo " "
echo "${Y}1. XFCE($total_custom_xfce_setup)${NC}"
echo
echo "${Y}2. LXQT($total_custom_lxqt_setup)${NC}"
echo
echo "${Y}3. OPENBOX WM($total_custom_openbox_setup)${NC}"
echo
echo "${Y}4. MATE (Unstable)($total_custom_mate_setup)${NC}"
echo
echo "${Y}5. Gnome($total_custom_gnome_setup)(WIP, so expect bugs)${NC}"
echo
echo "${Y}6. Cinnamon($total_custom_cinnamon_setup)${NC}"
echo
echo "${Y}7. I3Wm($total_custom_i3wm_setup)${NC}"
echo
echo "${Y}8. Dwm($total_custom_dwm_setup)${NC}"
echo
echo "${Y}9. Bspwm($total_custom_bspwm_setup)${NC}"
echo
echo "${Y}10. Awesome($total_custom_awesome_setup)${NC}"
echo
echo "${Y}11. Fluxbox($total_custom_fluxbox_setup)${NC}"
echo
echo "${Y}12. IceWM($total_custom_icewm_setup)${NC}"
echo
select_an_option 12 1 desktop_answer
# set the variables based on chosen de
sys_icons_folder="$PREFIX/share/icons"
sys_themes_folder="$PREFIX/share/themes"
if [[ "$desktop_answer" == "1" ]]; then
de_name="xfce"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="startxfce4"
elif [[ "$desktop_answer" == "2" ]]; then
de_name="lxqt"
themes_folder="$sys_themes_folder"
icons_folder="$sys_icons_folder"
de_startup="startlxqt"
elif [[ "$desktop_answer" == "3" ]]; then
de_name="openbox"
themes_folder="$sys_themes_folder"
icons_folder="$sys_icons_folder"
de_startup="openbox-session"
elif [[ "$desktop_answer" == "4" ]]; then
de_name="mate"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="mate-session"
elif [[ "$desktop_answer" == "5" ]]; then
de_name="gnome"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="gnome-session-minimal"
elif [[ "$desktop_answer" == "6" ]]; then
de_name="cinnamon"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="cinnamon-session"
elif [[ "$desktop_answer" == "7" ]]; then
de_name="i3wm"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="i3"
elif [[ "$desktop_answer" == "8" ]]; then
de_name="dwm"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="dwm"
elif [[ "$desktop_answer" == "9" ]]; then
de_name="bspwm"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="bspwm"
elif [[ "$desktop_answer" == "10" ]]; then
de_name="awesome"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="awesome"
elif [[ "$desktop_answer" == "11" ]]; then
de_name="fluxbox"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="fluxbox"
elif [[ "$desktop_answer" == "12" ]]; then
de_name="icewm"
themes_folder="$HOME/.themes"
icons_folder="$HOME/.icons"
de_startup="icewm-session"
fi
banner
questions_theme_select
}
function questions_zsh_theme_select() {
print_msg "${BOLD} Select zsh theme"
echo
echo "${Y}1. My Zsh Theme (not customizable, made for my setup) ${NC}"
echo
echo "${Y}2. Powerlevel10k (highly customizable) ${NC}"
echo
echo "${Y}3. Pure (pretty, minimal and fast zsh prompt) ${NC}"
echo
select_an_option 3 1 chosen_zsh_theme
if [[ "$chosen_zsh_theme" == "1" ]]; then
selected_zsh_theme_name="td_zsh"
elif [[ "$chosen_zsh_theme" == "2" ]]; then
selected_zsh_theme_name="p10k_zsh"
elif [[ "$chosen_zsh_theme" == "3" ]]; then
selected_zsh_theme_name="pure_zsh"
fi
}
function questions_nerd_font_select() {
print_msg "Select nerd font you want to install...${B}"
echo
latest_nf_version=$(get_latest_release "ryanoasis" "nerd-fonts")
release_json=$(curl -sSL "https://api.github.com/repos/ryanoasis/nerd-fonts/releases/tags/${latest_nf_version}")
mapfile -t ASSET_NAMES < <(
jq -r '
.assets // []
| map(select(.name | endswith(".tar.xz")))
| .[].name
' <<<"$release_json"
)
FONT_DISPLAY=()
for asset in "${ASSET_NAMES[@]}"; do
FONT_DISPLAY+=("${asset%.tar.xz}")
done
((${#ASSET_NAMES[@]} == 0)) && {
print_failed "No .tar.xz fonts found for ${latest_nf_version}." >&2
exit 1
}
term_width=$(tput cols 2>/dev/null || echo 80)
(
for i in "${!FONT_DISPLAY[@]}"; do
printf "%3d) %s\n" "$((i + 1))" "${FONT_DISPLAY[$i]}"
done
) | pr -2 -t -w"$term_width"
echo
select_an_option "${#ASSET_NAMES[@]}" 1 nerd_choice
sel_asset_name="${ASSET_NAMES[$((nerd_choice - 1))]}"
sel_base_name="${FONT_DISPLAY[$((nerd_choice - 1))]}"
}
function questions_setup_manual() {
ask_to_chose_de
banner
print_msg "${BOLD}Select browser you want to install"
echo
echo "${Y}1. firefox${NC}"
echo
echo "${Y}2. chromium${NC}"
echo
echo "${Y}3. firefox & chromium (both)${NC}"
echo
echo "${Y}4. Skip${NC}"
echo
select_an_option 4 1 browser_answer
case "$browser_answer" in
1) installed_browser="firefox" ;;
2) installed_browser="chromium" ;;
3) installed_browser="all" ;;
4) installed_browser="skip" ;;
esac
banner
print_msg "${BOLD}Select IDE you want to install"
echo
echo "${Y}1. VS Code${NC}"
echo
echo "${Y}2. Geany${NC}"
echo
echo "${Y}3. NeoVim${NC}"
echo
echo "${Y}4. All of them${NC}"
echo
echo "${Y}5. Skip${NC}"
echo
select_an_option 5 1 ide_answer
case "$ide_answer" in
1) installed_ide="code" ;;
2) installed_ide="geany" ;;
3) installed_ide="neovim" ;;
4) installed_ide="all" ;;
5) installed_ide="skip" ;;
esac
echo
if [[ "$installed_ide" == "neovim" ]] || [[ "$installed_ide" == "all" ]]; then
print_msg "${BOLD}Select neovim config"
echo
echo "${Y}1. Stock${NC}"
echo
echo "${Y}2. NvChad${NC}"
echo
echo "${Y}3. LazyVim${NC}"
echo
echo "${Y}4. mynvim (my personal neovim config)${NC}"
echo
select_an_option 4 2 select_neovim_distro
case "$select_neovim_distro" in
1) installed_nvim_distro="stock" ;;
2) installed_nvim_distro="nvchad" ;;
3) installed_nvim_distro="lazyvim" ;;
4) installed_nvim_distro="mynvim" ;;
esac
fi
banner
print_msg "${BOLD}Select Media Player you want to install"
echo
echo "${Y}1. Vlc${NC}"
echo
echo "${Y}2. Mpv${NC}"
echo
echo "${Y}3. Both${NC}"
echo
echo "${Y}4. Skip${NC}"
echo
select_an_option 4 1 player_answer
case "$player_answer" in
1) installed_media_player="vlc" ;;
2) installed_media_player="mpv" ;;
3) installed_media_player="all" ;;
4) installed_media_player="skip" ;;
esac
banner
print_msg "${BOLD}Select Photo Editor${NC}"
echo
echo "${Y}1. Gimp${NC}"
echo
echo "${Y}2. Inkscape${NC}"
echo
echo "${Y}3. Gimp & Inkscape (both)${NC}"
echo
echo "${Y}4. Skip${NC}"
echo
select_an_option 4 1 photo_editor_answer
case "$photo_editor_answer" in
1) installed_photo_editor="gimp" ;;
2) installed_photo_editor="inkscape" ;;
3) installed_photo_editor="all" ;;
4) installed_photo_editor="skip" ;;
esac
banner
print_msg "${BOLD}Do you want to install wine in termux ${C}(without proot-distro)"
echo
echo "${Y}1. Native ${C}(can run only arm64 based exe)${NC}"
echo
echo "${Y}2. Mobox ${C}(Un-maintained) ${NC}"
echo
print_msg "${B}Know More About Mobox:- https://github.com/olegos2/mobox/"
echo
echo "${Y}3. Wine Hangover${NC}"
echo
echo "${Y}4. Skip${NC}"
echo
select_an_option 4 1 wine_answer
case "$wine_answer" in
1) installed_wine="stock" ;;
2) installed_wine="mobox" ;;
3) installed_wine="wine_hangover" ;;
4) installed_wine="skip" ;;
esac
banner
confirmation_y_or_n "Do you want to Configure Hardware Acceleration" enable_hw_acc
banner
print_msg " By default, it only adds 4-5 wallpapers"
echo
print_msg "${R}This is a 1GB+ collection (Thanks:-JaKooLit)"
echo
confirmation_y_or_n "Do you want to add some more wallpapers" ext_wall_answer
banner
print_msg "${BOLD}Select Your shell${NC}"
echo
echo "${Y}1. Zsh + zinit${NC}"
echo
echo "${Y}2. Custom Bash prompt + ble.sh (ble.sh kind of buggy right now)${NC}"
echo
echo "${Y}3. Custom Bash prompt${NC}"
echo
select_an_option 4 1 chosen_shell_answer
case "$chosen_shell_answer" in
1) chosen_shell_name="zsh" ;;
2) chosen_shell_name="bash_with_ble" ;;
3) chosen_shell_name="bash" ;;
esac
if [[ "$chosen_shell_name" == "zsh" ]]; then
questions_zsh_theme_select
fi
banner
echo
print_msg "${B}Know More About Terminal Utility:- https://github.com/sabamdarif/termux-desktop/blob/main/docs/see-more.md#hammer_and_wrenchlearn-about-terminal-utilities"
echo
confirmation_y_or_n "Do you want install some terminal utility to make better terminal exprience" terminal_utility_setup_answer
banner
questions_nerd_font_select
banner
echo -e "${R}[${C}-${R}]${B} File Manager Tools Enhancement${NC}
${B}Overview:${NC}
This option enhances your file manager with powerful right-click menu features.
${B}Key Features:${NC}
• Media Operations
- Video processing and conversion
- Image editing and optimization
- Audio file management
- PDF manipulation
• File Management
- Archive compression/extraction
- File permissions control
- Document processing
- File encryption
- Hash verification
• Additional Features
- Custom scripts integration
- Batch processing
- Quick actions menu
${B}How to Access:${NC}
Access these features through the 'Scripts' menu in your file manager's right-click context menu.
${NC}"
confirmation_y_or_n "Do you want File Manager Tools tailored with powerful extra features" fm_tools
banner
print_msg "${BOLD} Select Gui Mode"
echo
echo "${Y}1. Termux:x11${NC}"
echo
echo "${Y}2. Both Termux:x11 and VNC${NC}"
echo
select_an_option 2 1 gui_mode_num
# set gui_mode and display_number value
if [[ "$gui_mode_num" == "1" ]]; then
gui_mode="termux_x11"
display_number="0"
gui_mode_name="Termux:x11"
elif [[ "$gui_mode_num" == "2" ]]; then
gui_mode="both"
display_number="0"
gui_mode_name="Both"
fi
banner
confirmation_y_or_n "Do you want to start the desktop at Termux startup" de_on_startup
if [[ "$de_on_startup" == "y" && "$gui_mode" == "both" ]]; then
print_msg "You chose both vnc and termux:x11 to access gui mode"
echo
print_msg "Which will be your default"
echo
echo "${Y}1. Termux:x11${NC}"
echo
echo "${Y}2. Vnc${NC}"
echo
select_an_option 2 1 autostart_gui_mode_num
if [[ "$autostart_gui_mode_num" == "1" ]]; then
default_gui_mode="termux_x11"
elif [[ "$autostart_gui_mode_num" == "2" ]]; then
default_gui_mode="vnc"
fi
fi
banner
echo -e "
${R}[${C}-${R}]${G}${BOLD} Linux Distro Container:- ${NC}
It will help you to install apps that aren't available in Termux.
So it will set up a Linux distro container and add options to install those apps.
Also, you can launch those installed apps from Termux like other apps.
"
echo "Learn More:- https://github.com/sabamdarif/termux-desktop/blob/main/docs/proot-container.md"
echo
confirmation_y_or_n "Do you want to add a Linux container" distro_add_answer
}
function setup_device_gpu_model() {
if [[ -z "$GPU_NAME" ]] || [[ "$GPU_NAME" == "unknown" ]]; then
while true; do
banner
print_warn "Unable to auto detect GPU"
echo
print_msg "${BOLD}Please Select Your Device GPU"
echo
echo "${Y}1. Adreno${NC}"
echo
echo "${Y}2. Mali${NC}"
echo
echo "${Y}3. Xclipse${NC}"
echo
echo "${Y}4. Others (Unstable)${NC}"
echo
read -r -p "${Y} Enter your choise [1-4]: ${NC}" device_gpu_model
if [[ "$device_gpu_model" =~ ^[1-4]$ ]]; then
print_success "Continuing with answer: $device_gpu_model"
break
else
print_warn "Invalid input, Please enter a number between 1 and 4"
fi
done
# set gpu model name
case "$device_gpu_model" in
1) GPU_NAME="adreno" ;;
2) GPU_NAME="mali" ;;
3) GPU_NAME="xclipse" ;;
4) GPU_NAME="others" ;;
esac
fi
}
# distro hardware accelrration related questions
function distro_hw_questions() {
if [[ "$distro_add_answer" == "y" ]]; then
case "$termux_hw_answer" in
"virgl" | "virgl_vulkan")
if [[ "$GPU_NAME" == "adreno" ]]; then
banner
print_msg "${BOLD}Select Hardware Acceleration Driver For Linux Container"
echo "${Y}1. VirGL + ANGLE (GPU Passthrough via virpipe)${NC}"
echo
echo "${Y}2. Turnip (Native Adreno Vulkan Driver)${NC}"
echo
select_an_option 2 1 pd_hw_answer_num
case "$pd_hw_answer_num" in
1) pd_hw_answer="virgl" ;;
2) pd_hw_answer="turnip" ;;
esac
pd_hw_answer=$([ "$pd_hw_answer_num" == "1" ] && echo "virgl" || echo "turnip")
else
pd_hw_answer="virgl"
fi
;;
"freedreno_kgsl" | "mesa_freedreno" | "mesa_zink_freedreno")
pd_hw_answer="turnip"
;;
*)
banner
print_msg "${BOLD}Select Hardware Acceleration Driver For Linux Container"
echo
print_msg "If You Skip It, It Will Use The Previous Selection"
echo
echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL Translation)${NC}"
echo
echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
echo
echo "${Y}3. Turnip (Native Adreno Vulkan Driver)${NC}"
echo
select_an_option 3 1 pd_hw_answer_num
case "$pd_hw_answer_num" in
1) pd_hw_answer="zink" ;;
2) pd_hw_answer="virgl" ;;
3) pd_hw_answer="turnip" ;;
esac
;;
esac
fi
}
# hardware accelrration related questions
#NOTE: this get called first in hw_questions function
function exp_vulkan_support() {
print_msg "${BOLD}First Read This"
echo
print_msg "${B}This:- https://github.com/sabamdarif/termux-desktop/blob/main/docs/hw-acceleration.md"
echo
print_msg "${BOLD}Select the vulkan driver"
echo
if [[ "${termux_arch}" == "aarch64" ]]; then
echo "${Y}1. vulkan-wrapper-android${NC}"
echo
echo "${Y}2. vulkan-wrapper-android (leegao's fork)${NC}"
echo
echo "${Y}3. mesa-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
echo
echo "${Y}4. mesa-zink-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
echo
echo "${Y}5. mesa-vulkan-icd-freedreno (Kgsl) (adreno only)${NC}"
echo
echo "${Y}6. will use the old virgl way${NC}"
echo
select_an_option 6 1 exp_termux_vulkan_hw_answer_num
# set gpu api name
case "$exp_termux_vulkan_hw_answer_num" in
1) exp_termux_vulkan_hw_answer="vulkan_wrapper_android" ;;
2) exp_termux_vulkan_hw_answer="vulkan_wrapper_android_leegaos_fork" ;;
3) exp_termux_vulkan_hw_answer="mesa_freedreno" ;;
4) exp_termux_vulkan_hw_answer="mesa_zink_freedreno" ;;
5) exp_termux_vulkan_hw_answer="freedreno_kgsl" ;;
6) exp_termux_vulkan_hw_answer="skip" ;;
esac
else
echo "${Y}1. vulkan-wrapper-android${NC}"
echo
echo "${Y}2. mesa-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
echo
echo "${Y}3. mesa-zink-vulkan-icd-freedreno (Turnip) (adreno only)${NC}"
echo
echo "${Y}4. mesa-vulkan-icd-freedreno (Kgsl) (adreno only)${NC}"
echo
echo "${Y}5. will use the old virgl way${NC}"
echo
select_an_option 5 1 exp_termux_vulkan_hw_answer_num
# set gpu api name
case "$exp_termux_vulkan_hw_answer_num" in
1) exp_termux_vulkan_hw_answer="vulkan_wrapper_android" ;;
2) exp_termux_vulkan_hw_answer="mesa_freedreno" ;;
3) exp_termux_vulkan_hw_answer="mesa_zink_freedreno" ;;
4) exp_termux_vulkan_hw_answer="freedreno_kgsl" ;;
5) exp_termux_vulkan_hw_answer="skip" ;;
esac
fi
}
function exp_termux_gl_hw_support() {
banner
echo
print_msg "${BOLD}It will be used to enable opengl support"
echo
echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL) + VirGL Server${NC}"
echo
echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
echo
echo "${Y}3. VirGL + ANGLE OpenGL Backend${NC}"
echo
echo "${Y}4. VirGL + ANGLE Vulkan Backend${NC}"
echo
echo "${Y}5. Mesa Zink + VirGL (Vulkan-to-OpenGL via VirGL)${NC}"
echo
echo "${Y}6. Mesa Zink Direct (Native Vulkan-to-OpenGL)${NC}"
echo
echo "${Y}7. Mesa Zink Direct with Mesa-zink (Native Vulkan-to-OpenGL)${NC}"
echo
select_an_option 7 1 exp_termux_gl_hw_answer_num
# set gpu api name
case "$exp_termux_gl_hw_answer_num" in
1) exp_termux_gl_hw_answer="zink" ;;
2) exp_termux_gl_hw_answer="virgl" ;;
3) exp_termux_gl_hw_answer="virgl_angle" ;;
4) exp_termux_gl_hw_answer="virgl_vulkan" ;;
5) exp_termux_gl_hw_answer="zink_virgl" ;;
6) exp_termux_gl_hw_answer="zink_with_mesa" ;;
7) exp_termux_gl_hw_answer="zink_with_mesa_zink" ;;
esac
termux_hw_answer="${exp_termux_gl_hw_answer}"
distro_hw_questions
}
#NOTE: it first call exp_vulkan_support then if user select vulkan_wrapper_android the it will go for exp_termux_gl_hw_answer (as name suggest it setup the opengl driver for termux) and user type 4=skip then it will go for everything using virgl option (it's kind of same as exp_termux_gl_hw_answer), then when it done for termux part it will call distro_hw_questions to setup hwa for the selected proot-distro
function hw_questions() {
banner
exp_vulkan_support
if [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android" ]] || [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android_leegaos_fork" ]] || [[ "$exp_termux_vulkan_hw_answer" == "mesa_freedreno" ]] || [[ "$exp_termux_vulkan_hw_answer" == "mesa_zink_freedreno" ]]; then
exp_termux_gl_hw_support
elif [[ "$exp_termux_vulkan_hw_answer" == "freedreno_kgsl" ]]; then
termux_hw_answer="${exp_termux_vulkan_hw_answer}"
distro_hw_questions
elif [[ "$exp_termux_vulkan_hw_answer" == "skip" ]]; then
print_msg "${BOLD}First Read This"
echo
print_msg "${B}This:- https://github.com/sabamdarif/termux-desktop/blob/main/docs/hw-acceleration.md"
echo
print_msg "${BOLD}Select Hardware Acceleration API"
echo
echo
print_msg "${BOLD}Select Hardware Acceleration API"
echo
echo "${Y}1. Mesa Zink (Vulkan-to-OpenGL) + VirGL Server${NC}"
echo
echo "${Y}2. VirGL (GPU Passthrough via virpipe)${NC}"
echo
echo "${Y}3. VirGL + ANGLE OpenGL Backend${NC}"
echo
echo "${Y}4. VirGL + ANGLE Vulkan Backend${NC}"
echo
echo "${Y}5. Mesa Zink + VirGL (Vulkan-to-OpenGL via VirGL)${NC}"
echo
select_an_option 5 1 termux_hw_answer_num
# set gpu api name
case "$termux_hw_answer_num" in
1) termux_hw_answer="zink" ;;
2) termux_hw_answer="virgl" ;;
3) termux_hw_answer="virgl_angle" ;;
4) termux_hw_answer="virgl_vulkan" ;;
5) termux_hw_answer="zink_virgl" ;;
esac
distro_hw_questions
fi
}
# distro related questions
function distro_type_select() {
print_msg "${BOLD}Select the distro type"
echo " "
echo "${G}chroot-distro:- ${B}https://github.com/sabamdarif/chroot-distro${NC}"
echo " "
echo "${G}proot-distro:- ${B}https://github.com/termux/proot-distro${NC}"
echo " "
echo "${Y}1. Proot Distro${NC}"
echo " "
echo "${Y}2. Chroot Distro${NC}"
echo " "
select_an_option 2 1 distro_type_answer
case "$distro_type_answer" in
1) selected_distro_type="proot" ;;
2) selected_distro_type="chroot" ;;
*) selected_distro_type="proot" ;;
esac
}
function choose_distro() {
print_msg "${BOLD}Select Linux Distro You Want To Add"
echo " "
echo "${Y}1. Debian${NC}"
echo " "
echo "${Y}2. Ubuntu${NC}"
echo " "
echo "${Y}3. Arch (Unstable | isn't fully suppoted by AppStore yet)${NC}"
echo " "
echo "${Y}4. Fedora${NC}"
echo " "
select_an_option 4 1 distro_answer
case "$distro_answer" in
1) selected_distro="debian" ;;
2) selected_distro="ubuntu" ;;
3) selected_distro="archlinux" ;;
4) selected_distro="fedora" ;;
*) selected_distro="debian" ;;
esac
}
function setup_user_name_only() {
echo
print_msg "${BOLD}Create user account"
echo
while true; do
echo " "
print_msg "Default Password Will Be Set, Because Sometimes It Might Ask You For Password"
echo
print_msg "Password:-${C}root"
# set password to root
pass=root
echo
while true; do
read -r -p "${R}[${C}-${R}]${G} Input username [Lowercase]: ${NC}" user_name
if [[ -z "$user_name" ]]; then
print_warn "You can't leave the username empty. Please enter a valid username."
elif [[ "$user_name" =~ \ ]]; then
print_warn "Username cannot contain spaces. Please enter a valid username."
else
break
fi
done
echo
local choice
read -r -p "${R}[${C}-${R}]${Y} Do you want to continue with username ${C}$user_name ${Y}? (y/n) : ${NC}" choice
echo
choice="${choice:-y}"
echo
print_success "Continuing with answer: $choice"
sleep 0.2
case $choice in
[yY]*)
print_success "Continuing with username ${C}$user_name"
break
;;
[nN]*)
print_msg "Please provide username again."
echo
;;
*)
print_failed "Invalid input, Please enter y or n"
;;
esac
done
}
function setup_user_name_and_pass() {
echo
print_msg "${BOLD}Create user account"
echo
while true; do
while true; do
read -r -p "${R}[${C}-${R}]${G}Input username [Lowercase]: ${NC}" user_name
if [[ -z "$user_name" ]]; then
print_warn "You can't leave the username empty. Please enter a valid username."
elif [[ "$user_name" =~ \ ]]; then
print_warn "Username cannot contain spaces. Please enter a valid username."
else
break
fi
done
echo
while true; do
read -r -p "${R}[${C}-${R}]${G}Input Password (Minimum 4 characters): ${NC}" pass
if [[ -z "$pass" ]]; then
print_warn "You can't leave the password empty. Please enter a valid password."
elif [[ "$user_name" =~ \ ]]; then
print_warn "Password cannot contain spaces. Please enter a valid username."
elif [[ ${#pass} -lt 4 ]]; then
print_warn "Password must be at least 4 characters long. Please enter a longer password."
else
break
fi
done
echo
read -r -p "${R}[${C}-${R}]${Y}Do you want to continue with username ${C}$user_name ${Y}and password ${C}$pass${Y} ? (y/n) : ${NC}" choice
echo
choice="${choice:-y}"
echo
print_success "Continuing with answer: $choice"
echo ""
sleep 0.2
case $choice in
[yY]*)
print_success "Continuing with username ${C}$user_name ${G}and password ${C}$pass"
break
;;
[nN]*)
print_msg "Please provide username and password again."
echo
;;
*)
print_failed "Invalid input, Please enter y or n"
;;
esac
done
}
function distro_questions() {
banner
distro_type_select
choose_distro
banner
confirmation_y_or_n "Do you want to configure audio support for Linux distro container" pd_audio_config_answer
banner
confirmation_y_or_n "Do you want to create a normal user account ${C}(Recomended)" pd_useradd_answer
echo
if [[ "$pd_useradd_answer" == "n" ]]; then
print_msg "Skiping User Account Setup"
else
print_msg "${BOLD}Select user account type"
echo
echo "${Y}1. User with no password confirmation${NC}"
echo
echo "${Y}2. User with password confirmation${NC}"
echo
select_an_option 2 1 pd_pass_type
if [[ "$pd_pass_type" == "1" ]]; then
setup_user_name_only
elif [[ "$pd_pass_type" == "2" ]]; then
setup_user_name_and_pass
fi
fi
}
# it set all the value that wil be used for printing the setup configuration (in print_conf_info)
function define_value_name() {
# Gui mode
if [[ "$gui_mode" == "termux_x11" ]]; then
gui_mode_name="Termux:x11"
elif [[ "$gui_mode" == "both" ]]; then
gui_mode_name="Both"
fi
# autostart value
if [[ "$de_on_startup" == "y" ]]; then
autostart_value="Yes"
elif [[ "$de_on_startup" == "n" ]]; then
autostart_value="No"
fi
# browser
if [[ "$installed_browser" == "firefox" ]]; then
browser_name="Firefox"
elif [[ "$installed_browser" == "chromium" ]]; then
browser_name="Chromium"
elif [[ "$installed_browser" == "all" ]]; then
browser_name="Both Firefox and Chromium"
elif [[ "$installed_browser" == "skip" ]]; then
browser_name="Skip"
fi
# media player
if [[ "$installed_media_player" == "vlc" ]]; then
media_player_name="Vlc"
elif [[ "$installed_media_player" == "mpv" ]]; then
media_player_name="Mpv"
elif [[ "$installed_media_player" == "all" ]]; then
media_player_name="Both Vlc and Mpv"
elif [[ "$installed_media_player" == "skip" ]]; then
media_player_name="Skip"
fi
# Image Editor
if [[ "$installed_photo_editor" == "gimp" ]]; then
photo_editor_name="GIMP"
elif [[ "$installed_photo_editor" == "inkscape" ]]; then
photo_editor_name="Inkscape"
elif [[ "$installed_photo_editor" == "all" ]]; then
photo_editor_name="Both GIMP and Inkscape"
elif [[ "$installed_photo_editor" == "skip" ]]; then
photo_editor_name="Skip"
fi
# IDE
if [[ "$installed_ide" == "code" ]]; then
ide_name="VS Code (code-oss)"
elif [[ "$installed_ide" == "geany" ]]; then
ide_name="Geany"
elif [[ "$installed_ide" == "neovim" ]]; then
if [[ "$installed_nvim_distro" == "stock" ]]; then
neovim_distro="Stock"
elif [[ "$installed_nvim_distro" == "nvchad" ]]; then
neovim_distro="NvChad"
elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
neovim_distro="LazyVim"
elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
neovim_distro="MyNvim"
fi
ide_name="NeoVim ${neovim_distro}"
elif [[ "$installed_ide" == "all" ]]; then
ide_name="All"
elif [[ "$installed_ide" == "skip" ]]; then
ide_name="Skip"
fi
# WINE
if [[ "$installed_wine" == "stock" ]]; then
wine_type_name="Native"
elif [[ "$installed_wine" == "mobox" ]]; then
wine_type_name="Mobox"
elif [[ "$installed_wine" == "wine_hangover" ]]; then
wine_type_name="Wine Hangover"
elif [[ "$installed_wine" == "skip" ]]; then
wine_type_name="Skip"
fi
# Extra Wallpapers
if [[ "$ext_wall_answer" == "y" ]]; then
ext_wall_answer_confirmation="Yes"
elif [[ "$ext_wall_answer" == "n" ]]; then
ext_wall_answer_confirmation="No"
fi
# File Manager Tools
if [[ "$fm_tools" == "y" ]]; then
fm_tools_confirmation="Yes"
elif [[ "$fm_tools" == "n" ]]; then
fm_tools_confirmation="No"
fi
# Shell
if [[ "$chosen_shell_name" == "bash" ]]; then
current_shell_name="Bash"
elif [[ "$chosen_shell_name" == "bash_with_ble" ]]; then
current_shell_name="Bash (With Ble.sh)"
elif [[ "$chosen_shell_name" == "zsh" ]]; then
if [[ "$selected_zsh_theme_name" == "td_zsh" ]]; then
zsh_theme_name="My Zsh Theme"
elif [[ "$selected_zsh_theme_name" == "p10k_zsh" ]]; then
zsh_theme_name="Powerlevel10k"
elif [[ "$selected_zsh_theme_name" == "pure_zsh" ]]; then
zsh_theme_name="Pure"
fi
current_shell_name="Zsh ($zsh_theme_name)"
fi
# Terminal Utilities
if [[ "$terminal_utility_setup_answer" == "y" ]]; then
terminal_utility_setup_confirmation="Yes"
elif [[ "$terminal_utility_setup_answer" == "n" ]]; then
terminal_utility_setup_confirmation="No"
fi
# Nerd Font
if [[ "$install_type_answer" == "1" ]]; then
sel_font_name="$sel_base_name"
elif [[ "$install_type_answer" == "2" ]] || [[ "$install_type_answer" == "3" ]]; then
sel_font_name="0xProto"
else
sel_font_name="N/A"
fi
# Hardware Acceleration Status
if [[ "$enable_hw_acc" == "y" ]]; then
hw_acc_confirmation="Enabled"
elif [[ "$enable_hw_acc" == "n" ]]; then
hw_acc_confirmation="Disabled"
fi
# Vulkan Driver
if [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android" ]]; then
vulkan_driver_name="Vulkak Wrapper Android"
elif [[ "$exp_termux_vulkan_hw_answer" == "vulkan_wrapper_android_leegaos_fork" ]]; then
vulkan_driver_name="Vulkan Wrapper Android (leegao's fork)"
elif [[ "$exp_termux_vulkan_hw_answer" == "mesa_freedreno" ]]; then
vulkan_driver_name="Mesa ICD Freedreno"
elif [[ "$exp_termux_vulkan_hw_answer" == "mesa_zink_freedreno" ]]; then
vulkan_driver_name="Mesa Zink ICD Freedreno"
else
vulkan_driver_name="Might Not Support"
fi
# OpenGL Driver
if [[ "$termux_hw_answer" == "zink" ]]; then
opengl_driver_name="Zink"
elif [[ "$termux_hw_answer" == "virgl" ]]; then
opengl_driver_name="Virgl"
elif [[ "$termux_hw_answer" == "virgl_angle" ]]; then
opengl_driver_name="Virgl Angle"
elif [[ "$termux_hw_answer" == "virgl_vulkan" ]]; then
opengl_driver_name="VIRGL ANGLE (Vulkan)"
elif [[ "$termux_hw_answer" == "zink_virgl" ]]; then
opengl_driver_name="OpenGL ES (ZINK VIRGL)"
elif [[ "$termux_hw_answer" == "zink_with_mesa" ]]; then
opengl_driver_name="The vulkan-wrapper-android Driver With Mesa"
elif [[ "$termux_hw_answer" == "zink_with_mesa_zink" ]]; then
opengl_driver_name="The vulkan-wrapper-android Driver With Mesa-Zink"
elif [[ "$termux_hw_answer" == "freedreno" ]]; then
opengl_driver_name="Freedreno"
else
opengl_driver_name="Might Not Support"
fi
# Linux Distro Container
if [[ "$distro_add_answer" == "y" ]]; then
distro_container_confirmation="Enabled"
elif [[ "$distro_add_answer" == "n" ]]; then
distro_container_confirmation="Disabled"
fi
if [[ "$selected_distro_type" == "chroot" ]]; then
distro_type=CHROOT
elif [[ "$selected_distro_type" == "proot" ]]; then
distro_type=PROOT
else
distro_type="Unable to select distro type"
fi
# Distro User and Pass
if [[ "$pd_useradd_answer" == "y" ]]; then
distro_user_name="${user_name}"
if [[ -z "$pass" ]]; then
distro_pass="root (password will be disabled by default)"
else
distro_pass="${pass}"
fi
elif [[ "$pd_useradd_answer" == "n" ]]; then
distro_user_name="Null"
distro_pass="Null"
fi
# Distro Audio Support
if [[ "$pd_audio_config_answer" == "y" ]]; then
pd_audio_config_confirmation="Yes"
elif [[ "$pd_audio_config_answer" == "n" ]]; then
pd_audio_config_confirmation="No"
fi
# Distro Hardware Acceleration
if [[ "$enable_hw_acc" == "y" ]]; then
distro_hw_acc_confirmation="Enabled"
elif [[ "$enable_hw_acc" == "n" ]]; then
distro_hw_acc_confirmation="Disabled"
fi
# Distro Vulkan Driver
if [[ "$pd_hw_answer" == "zink" ]]; then
distro_vulkan_driver="Not Supported"
elif [[ "$pd_hw_answer" == "virgl" ]]; then
distro_vulkan_driver="Not Supported"
elif [[ "$pd_hw_answer" == "turnip" ]]; then
distro_vulkan_driver="Turnip"
elif [[ "$pd_hw_answer" == "freedreno" ]]; then
distro_vulkan_driver="Freedreno"
else
distro_vulkan_driver="Unable to select"
fi
# Distro OpenGL Driver
if [[ "$pd_hw_answer" == "zink" ]]; then
distro_opengl_driver="Zink"
elif [[ "$pd_hw_answer" == "virgl" ]]; then
distro_opengl_driver="Virgl"
elif [[ "$pd_hw_answer" == "virgl" ]]; then
distro_opengl_driver="Virgl"
elif [[ "$pd_hw_answer" == "turnip" ]]; then
distro_opengl_driver="Turnip"
elif [[ "$pd_hw_answer" == "freedreno" ]]; then
distro_opengl_driver="Freedreno"
else
distro_opengl_driver="Unable to select"
fi
# Distro Terminal Utilities
if [[ "$terminal_utility_setup_answer" == "y" ]]; then
distro_terminal_utility_setup_confirmation="Yes"
elif [[ "$terminal_utility_setup_answer" == "n" ]]; then
distro_terminal_utility_setup_confirmation="No"
fi
}
function print_conf_info() {
define_value_name
trap '' SIGINT SIGTSTP
banner
print_msg "Installation Configuration Summary"
echo
echo "${G}Desktop Environment${NC}"
echo " • Desktop: $(echo "$de_name" | tr '[:lower:]' '[:upper:]')"
echo " • Desktop Style: ${style_answer}) ${style_name}"
echo " • GUI Access: ${gui_mode_name}"
echo " • Auto-start: ${autostart_value}"
sleep 0.015
echo "${G}Applications${NC}"
echo " • Browser: ${browser_name}"
echo " • Media Player: ${media_player_name}"
echo " • Image Editor: ${photo_editor_name}"
echo " • IDE: ${ide_name}"
echo " • WINE: ${wine_type_name}"
sleep 0.015
echo "${G}Customization${NC}"
echo " • Extra Wallpapers: ${ext_wall_answer_confirmation}"
echo " • File Manager Tools: ${fm_tools_confirmation}"
sleep 0.015
echo "${G}Terminal Setup${NC}"
echo " • Shell: ${current_shell_name}"
echo " • Terminal Utilities: ${terminal_utility_setup_confirmation}"
echo " • Font: ${sel_font_name}"
sleep 0.015
echo "${G}Hardware Acceleration${NC}"
echo " • Status: ${hw_acc_confirmation}"
if [[ "$enable_hw_acc" == "y" ]]; then
echo " • GPU: $(echo "$GPU_NAME" | tr '[:lower:]' '[:upper:]')"
echo " • Vulkan Driver: ${vulkan_driver_name}"
echo " • OpenGL Driver: ${opengl_driver_name}"
fi
sleep 0.015
echo "${G}Linux Distro Container${NC}"
echo " • Distro Status: ${distro_container_confirmation}"
if [[ "$distro_add_answer" == "y" ]]; then
echo " • Distro Type: ${distro_type}"
echo " • Distribution: ${selected_distro}"
echo " • Distro Username: ${distro_user_name}"
echo " • Distro Pass: ${distro_pass}"
echo " • Audio Support: ${pd_audio_config_confirmation}"
fi
if [[ "$enable_hw_acc" == "y" ]]; then
echo " • Hardware Acceleration: ${distro_hw_acc_confirmation}"
echo " • Vulkan Driver: ${distro_vulkan_driver}"
echo " • OpenGL Driver: ${distro_opengl_driver}"
fi
echo " • Terminal Utilities: ${distro_terminal_utility_setup_confirmation}"
sleep 0.015
# Re-enable keyboard interruptions
trap - SIGINT SIGTSTP
wait_for_keypress
}
#########################################################################
#
# Select Install Type and load config
#
#########################################################################
function questions_install_type() {
banner
# Clear screen and show title first
print_msg "A Quick Overview"
echo
sleep 0.2
echo -e "${R}[${C}-${R}]${G} Key Terms:${NC}
• Generic: Pre-configured options that so far work best in most of the devices\n
• Recommended: Tested configurations with minimal known issues\n
• Hardware Acceleration: Uses your device's GPU for better graphics render\n
• Custom: Full control over all installation options\n
"
echo "${R}[${Y}!${R}]${R} Important Note: ${NC}"
echo -e "${B}
Generic is only recomended for beginners\n
For most users who are familiar with Termux, the custom option is recommended, as most features are only available in the custom option
${NC}"
# Show selection options
print_msg "Select Install Type"
echo " "
echo "${Y}1. Custom${NC}"
echo " "
echo "${Y}2. Generic (with hardware acceleration)${NC}"
echo " "
echo "${Y}3. Generic (without hardware acceleration)${NC}"
echo " "
select_an_option 3 1 install_type_answer
if [[ "$install_type_answer" == "1" ]]; then
questions_setup_manual
elif [[ "$install_type_answer" == "2" ]]; then
######################################################################
# ********* Generic Recomended With Hardware Acceleration ********** #
######################################################################
ask_to_chose_de
setup_device_gpu_model
# download configuration
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/generic.conf"
# shellcheck disable=SC1091
source generic.conf
check_and_delete "generic.conf"
local device_brand_name
device_brand_name=$(getprop ro.product.brand | cut -d ' ' -f 1)
if [[ "$GPU_NAME" == "adreno" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/hwa/adreno/generic-adreno.conf"
# shellcheck disable=SC1091
source generic-adreno.conf
check_and_delete "generic-adreno.conf"
elif [[ "$GPU_NAME" == "mali" ]]; then
if [[ $device_brand_name == samsung* ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/hwa/mali/samsung/generic-samsung-mali.conf"
# shellcheck disable=SC1091
source generic-samsung-mali.conf
check_and_delete "generic-samsung-mali.conf"
else
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/hwa/mali/generic-mali.conf"
# shellcheck disable=SC1091
source generic-mali.conf
check_and_delete "generic-mali.conf"
fi
else
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/hwa/generic-others.conf"
# shellcheck disable=SC1091
source generic-others.conf
check_and_delete "generic-others.conf"
fi
# setup extra config if it's lite mode install
if [[ "$LITE_MODE" == "1" || "$LITE_MODE" == "true" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/generic-lite.conf"
# shellcheck disable=SC1091
source generic-lite.conf
check_and_delete "generic-lite.conf"
fi
# create username for distro
banner
setup_user_name_only
elif [[ "$install_type_answer" == "3" ]]; then
######################################################################
# ******* Generic Recomended Without Hardware Acceleration ********* #
######################################################################
ask_to_chose_de
# download configuration
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/generic.conf"
# shellcheck disable=SC1091
source generic.conf
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/nohwa/generic-nohwa.conf"
# shellcheck disable=SC1091
source generic-nohwa.conf
check_and_delete "generic-nohwa.conf"
# setup extra config if it's lite mode install
if [[ "$LITE_MODE" == "1" || "$LITE_MODE" == "true" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/configuration/generic/generic-lite.conf"
# shellcheck disable=SC1091
source generic-lite.conf
check_and_delete "generic-lite.conf"
fi
# create username for distro
banner
setup_user_name_only
fi
}
function load_local_config() {
banner
local config_path="$1"
# Check if the file exists
if [[ ! -f "$config_path" ]]; then
print_failed "$config_path does not exist."
exit 1
fi
# Check if the file has a .conf extension
if [[ "$config_path" != *.conf ]]; then
print_failed "$config_path does not have a .conf extension."
exit 1
fi
# Check if the file is not empty (not 0KB)
if [[ ! -s "$config_path" ]]; then
print_failed "$config_path is empty."
exit 1
fi
print_success "Using the local configuration file..."
# shellcheck disable=SC1090
source "$config_path"
sleep 3
validate_required_vars
}
#########################################################################
#
# Update System, Install Required Packages Repo, Requirements checkup
#
#########################################################################
function chose_mirror() {
print_msg "${BOLD}Selecting best termux packages mirror please wait"
# unlink "$PREFIX/etc/termux/chosen_mirrors" &>/dev/null
# ln -s "$PREFIX/etc/termux/mirrors/all" "$PREFIX/etc/termux/chosen_mirrors" &>/dev/null
# pkg --check-mirror update
if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termux-fastest-repo"
chmod +x termux-fastest-repo
./termux-fastest-repo
check_and_delete "termux-fastest-repo"
fi
}
function update_sys() {
banner
if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
print_msg "${BOLD}Updating System...."
pacman -Syu --noconfirm
else
print_msg "Do you want to run a speed test to find the fastest repo for you?"
echo "The speed test will check all mirrors in all"
echo "mirror groups, or only the group you selected."
echo "This process may take some time."
confirmation_y_or_n "Do you want to continue" confirmation_speedtest
if [[ "$confirmation_speedtest" == "y" ]]; then
chose_mirror
fi
print_msg "${BOLD}Updating System...."
apt update -y -o Dpkg::Options::="--force-confnew"
apt upgrade -y -o Dpkg::Options::="--force-confnew"
fi
}
function get_termux_arch() {
APP_ARCH=$(uname -m)
SUPPORTED_ARCH="$(getprop ro.product.cpu.abilist)"
case "$APP_ARCH" in
aarch64) termux_arch="aarch64" ;;
armv7* | arm | armv8*) termux_arch="arm" ;;
esac
}
function try_to_autodetect_gpu() {
local gpu_egl
local gpu_vulkan
gpu_egl=$(getprop ro.hardware.egl)
gpu_vulkan=$(getprop ro.hardware.vulkan)
detected_gpu="$(echo -e "$gpu_egl\n$gpu_vulkan" | sort -u | tr '\n' ' ' | sed 's/ $//')"
if echo "$detected_gpu" | grep -iq "adreno"; then
GPU_NAME="adreno"
elif echo "$detected_gpu" | grep -iqE "mali|meow"; then
GPU_NAME="mali"
elif echo "$detected_gpu" | grep -iqE "xclipse|samsung"; then
GPU_NAME="xclipse"
else
GPU_NAME="unknown"
fi
}
function check_system_requirements() {
while true; do
local errors=0
clear
# Disable keyboard interruptions
trap '' SIGINT SIGTSTP
printf "%s############################################################\n" "$C"
printf "%s# #\n" "$C"
printf "%s# ▀█▀ █▀▀ █▀█ █▀▄▀█ █ █ ▀▄▀ █▀▄ █▀▀ █▀ █▄▀ ▀█▀ █▀█ █▀█ #\n" "$C"
printf "%s# █ ██▄ █▀▄ █ █ █▄█ █ █ █▄▀ ██▄ ▄█ █ █ █ █▄█ █▀▀ #\n" "$C"
printf "%s# #\n" "$C"
printf "%s################# System Compatibility Check ###############%s\n" "$C" "$NC"
echo " "
sleep 0.3
# Check if running on Android
ANDROID_VERSION=$(getprop ro.build.version.release | cut -d'.' -f1)
if [[ "$(uname -o)" == "Android" ]]; then
if [[ "$ANDROID_VERSION" -ge 8 ]]; then
print_success "Running on: ${NC}Android $ANDROID_VERSION"
else
print_failed "Running on: ${NC}Android $ANDROID_VERSION is not recomended"
((errors++))
fi
else
print_failed "Not running on Android"
((errors++))
fi
sleep 0.2
# Android device soc & model details
MODEL="$(getprop ro.product.brand) $(getprop ro.product.model)"
print_success "Device: ${NC}$MODEL"
sleep 0.2
PROCESSOR_BRAND_NAME="$(getprop ro.soc.manufacturer)"
PROCESSOR_NAME="$(getprop ro.soc.model)"
HARDWARE="$(getprop ro.hardware)"
if [[ -n "$PROCESSOR_BRAND_NAME" && -n "$PROCESSOR_NAME" ]]; then
print_success "SOC: ${NC}$PROCESSOR_BRAND_NAME $PROCESSOR_NAME"
else
print_success "SOC: ${NC}$HARDWARE"
fi
sleep 0.2
# Check GPU
try_to_autodetect_gpu
if [[ "$GPU_NAME" == "adreno" ]] || [[ "$GPU_NAME" == "mali" ]] || [[ "$GPU_NAME" == "xclipse" ]]; then
print_success "GPU: ${NC}$GPU_NAME"
else
print_warn "Unknown GPU: ${NC}$GPU_NAME"
fi
sleep 0.2
# Check architecture
if [[ "$termux_arch" == "aarch64" ]] || [[ "$termux_arch" == "arm" ]]; then
print_success "App architecture: ${NC}$APP_ARCH"
else
print_failed "Unsupported architecture: $APP_ARCH, requires aarch64/arm/armv7*/armv8*"
((errors++))
fi
sleep 0.2
# Check for termux app requirements
if [[ -d "$PREFIX" ]]; then
print_success "Termux PREFIX: ${NC}Directory found"
sleep 0.2
local latest_termux_app_tag
latest_termux_app_tag=$(get_latest_release "termux" "termux-app")
if [[ "$TERMUX_VERSION" == "${latest_termux_app_tag#v}" ]]; then
print_success "Termux Version: ${NC}$TERMUX_VERSION"
sleep 0.2
local termux_build
termux_build=$(echo "$TERMUX_APK_RELEASE" | awk '{print tolower($0)}')
if [[ "$termux_build" == "github" ]] || [[ "$termux_build" == "fdroid" ]]; then
print_success "Termux Build: ${NC}$TERMUX_APK_RELEASE"
sleep 0.2
else
print_failed "$TERMUX_APK_RELEASE build is not recomended"
echo "${NC} Update Termux:- https://github.com/termux/termux-app/releases ${NC}"
sleep 0.2
fi
else
print_warn "Termux Version: ${NC}$TERMUX_VERSION (Not Recomended)"
if [[ $(getprop ro.product.cpu.abi) == "arm64-v8a" ]]; then
echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_arm64-v8a.apk${NC}"
elif [[ $(getprop ro.product.cpu.abi) == "armeabi-v7a" ]]; then
echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_armeabi-v7a.apk${NC}"
else
echo "${R}[${G}!${R}]${G} Update Termux:- https://github.com/termux/termux-app/releases/download/${latest_termux_app_tag}/termux-app_${latest_termux_app_tag}+github-debug_universal.apk${NC}"
fi
sleep 0.2
fi
else
print_failed "Termux PREFIX: directory not found"
((errors++))
sleep 0.2
fi
# Check available storage space
FREE_SPACE=$(df -h "$HOME" | awk 'NR==2 {print $4}')
if [[ $(df "$HOME" | awk 'NR==2 {print $4}') -gt 4194304 ]]; then
print_success "Available storage: ${NC}$FREE_SPACE"
else
print_warn "Low storage space: ${NC}$FREE_SPACE (4GB recommended)"
fi
sleep 0.2
# Check RAM
TOTAL_RAM=$(free -htm | awk '/Mem:/ {print $2}')
if [[ $(free -m | awk 'NR==2 {print $2}') -gt 2048 ]]; then
print_success "RAM: ${NC}${TOTAL_RAM}"
else
print_warn "Low RAM: ${NC}${TOTAL_RAM} (2GB recommended)"
fi
sleep 0.2
# Check termux x11
if cmd package list packages --user 0 -e -f | sed 's/package://; s/\.apk=/\.apk /' | grep -q "com.termux.x11"; then
print_success "Termux-x11: ${NC}Installed"
else
local latest_termux_x11_tag
latest_termux_x11_tag=$(get_latest_release "termux" "termux-x11")
print_failed "Termux-x11: ${NC}Not Installed"
if [[ $(getprop ro.product.cpu.abi) == "arm64-v8a" ]]; then
print_msg "${BOLD}Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-arm64-v8a-debug.apk"
elif [[ $(getprop ro.product.cpu.abi) == "armeabi-v7a" ]]; then
print_msg "${BOLD}Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-armeabi-v7a-debug.apk"
else
print_msg "${BOLD}Install Termux-x11:- ${NC}https://github.com/termux/termux-x11/releases/download/${latest_termux_x11_tag}/app-universal-debug.apk"
fi
((errors++))
fi
# Check termux API
if cmd package list packages --user 0 -e -f | sed 's/package://; s/\.apk=/\.apk /' | grep -q "com.termux.api"; then
IS_TERMUX_API_INSTALLED=true
print_success "Termux-API: ${NC}Installed"
else
local latest_termux_api_tag
latest_termux_api_tag=$(get_latest_release "termux" "termux-api")
print_failed "Termux-API: ${NC}Not Installed"
print_msg "${BOLD}Install Termux-API:- ${NC}https://github.com/termux/termux-api/releases/download/${latest_termux_api_tag}/termux-api-app_${latest_termux_api_tag}+github-debug.apk"
((errors++))
fi
echo " "
if [[ $errors -eq 0 ]]; then
print_success "All system requirements met!"
sleep 0.2
return 0
else
while true; do
print_failed "Found $errors error(s). System requirements not met."
sleep 0.2
print_msg "Type 'a' to check again"
read -r -p "${R}[${C}-${R}]${Y}${BOLD} Do you want to continue anyway (Not Recomended) ${Y}(y/n/a) ${NC}" sys_requirements_check
case $sys_requirements_check in
[yY]*)
echo
print_success "Continuing aniway..."
echo
sleep 0.2
break 2
;;
[aA]*)
echo
print_success "Starting check again..."
echo
sleep 0.2
break
;;
[nN]*)
trap - SIGINT SIGTSTP
exit 1
;;
*)
echo
print_failed "Invalid input. Please enter 'y' / 'n' / 'a'."
echo
;;
esac
done
log_debug "System requirements not met $sys_requirements_check"
fi
done
}
function print_recomended_msg() {
check_system_requirements
echo
print_msg "${BOLD}Pre-Installation Requirements"
echo
echo "${G}Essential Steps:${NC}"
echo " • Start with a clean installation"
echo " • Ensure at least 1GB of available data"
echo " • Use a stable internet connection or VPN"
echo
echo "${G}Device Settings:${NC}"
echo " • Enable 'Keep screen on' in Termux settings"
if [[ "$ANDROID_VERSION" -ge 12 ]]; then
echo " • Disable Phantom Process Killer (Android 12+ requirement)"
fi
echo
echo "${G}Important Notes:${NC}"
echo " • Keep Termux open during the entire installation"
echo " • Review all README documentation carefully"
echo " • In the multi selection option press enter to go with the default option"
echo
# Re-enable keyboard interruptions
trap - SIGINT SIGTSTP
wait_for_keypress
}
function install_required_packages() {
banner
print_msg "${BOLD}Installing required packages..."
echo
if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
package_install_and_check "wget git jq curl tar xz-utils gzip libpopt termux-am termux-api"
else
package_install_and_check "wget git jq curl tar xz-utils gzip libpopt termux-am x11-repo tur-repo termux-api"
fi
}
function recheck_basic_packages() {
print_msg "${BOLD}Checking required packages..."
local max_retries=3
local retry_count=0
local basic_packages=("wget" "git" "jq" "curl" "tar" "tar" "gzip" "termux-am" "termux-api-start")
local pack
while [[ "$retry_count" -le "$max_retries" ]]; do
local missing_packages=()
for pack in "${basic_packages[@]}"; do
print_msg "Checking command $pack"
if ! command -v "$pack" >/dev/null 2>&1; then
missing_packages+=("$pack")
fi
done
[[ ${#missing_packages[@]} -eq 0 ]] && return 0
((retry_count++))
print_msg "Attempt $retry_count: Installing missing packages..."
print_msg "Missing packages: ${missing_packages[*]}"
install_required_packages
done
print_failed "Error: Failed to install packages after 3 attempts"
print_failed "Missing packages: ${missing_packages[*]}"
exit 1
}
function install_desktop() {
log_debug "Starting desktop installation" "Desktop: $de_name"
banner
if [[ "$de_name" == "xfce" ]]; then
print_msg "${BOLD}Installing Xfce4 Desktop"
package_install_and_check "xfce4 xfce4-goodies xfce4-pulseaudio-plugin xfce4-battery-plugin xfce4-docklike-plugin xfce4-notifyd-static xfce4-cpugraph-plugin kvantum"
elif [[ "$de_name" == "lxqt" ]]; then
print_msg "${BOLD}Installing Lxqt Desktop"
echo
package_install_and_check "lxqt openbox gtk3 papirus-icon-theme xorg-xsetroot kvantum"
elif [[ "$de_name" == "openbox" ]]; then
print_msg "${BOLD}Installing Openbox WM"
echo
package_install_and_check "openbox polybar xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint kvantum"
elif [[ "$de_name" == "mate" ]]; then
print_msg "${BOLD}Installing MATE"
echo
package_install_and_check "mate*"
package_install_and_check "marco mousepad xfce4-taskmanager eog kvantum"
elif [[ "$de_name" == "i3wm" ]]; then
print_msg "${BOLD}Installing i3WM"
package_install_and_check "i3"
elif [[ "$de_name" == "dwm" ]]; then
print_msg "${BOLD}Installing DWM"
package_install_and_check "dwm"
elif [[ "$de_name" == "bspwm" ]]; then
print_msg "${BOLD}Installing BSPWM"
package_install_and_check "bspwm lxappearance xorg-xsetroot rofi feh"
elif [[ "$de_name" == "awesome" ]]; then
print_msg "${BOLD}Installing AWESOME WM"
package_install_and_check "awesome"
elif [[ "$de_name" == "fluxbox" ]]; then
print_msg "${BOLD}Installing Fluxbox WM"
echo
package_install_and_check "fluxbox xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint"
elif [[ "$de_name" == "icewm" ]]; then
print_msg "${BOLD}Installing Ice WM"
echo
package_install_and_check "icewm"
package_install_and_check "xdg-menu"
elif [[ "$de_name" == "gnome" ]]; then
print_msg "${BOLD}Installing Gnome"
echo
mkdir gnome_packages_files
cd gnome_packages_files || exit 1
if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
download_and_extract "https://github.com/sabamdarif/termux-desktop/releases/download/gnome-shell/debs-${termux_arch}.zip"
download_file "https://github.com/sabamdarif/Termux-AppStore/releases/download/files/refine_0.5.10_${termux_arch}.deb"
dpkg --configure -a
apt --fix-broken install -y
apt install ./*deb -y
apt install --fix-missing -y
elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
download_and_extract "https://github.com/sabamdarif/termux-desktop/releases/download/gnome-shell/pkgs-${termux_arch}.zip"
download_file "https://github.com/sabamdarif/Termux-AppStore/releases/download/files/refine_0.5.10_${termux_arch}.pkg.tar.xz"
pacman -U --noconfirm ./*.pkg.tar.xz
else
print_failed "Unsupported package manger, you need APT / PACMAN"
exit 1
fi
cd ..
check_and_delete "gnome_packages_files"
package_install_and_check "xfce4-terminal eog"
elif [[ "$de_name" == "cinnamon" ]]; then
print_msg "${BOLD}Installing Cinnamon"
echo
package_install_and_check "cinnamon nemo gnome-terminal gnome-screenshot eog"
fi
if [[ "$LITE_MODE" != "1" && "$LITE_MODE" != "true" ]]; then
package_install_and_check "file-roller pavucontrol gnome-font-viewer evince galculator xorg-xrdb"
fi
# Uncomment if additional package installation is needed
# if [[ "$distro_add_answer" == "y" ]]; then
# package_install_and_check "xdg-utils"
# fi
print_to_config "de_startup"
print_to_config "de_name"
print_to_config "themes_folder"
print_to_config "icons_folder"
log_debug "Desktop installation process done"
}
function ext_setup_for_stock() {
if [[ "$de_name" == "icewm" ]]; then
print_msg "Genarating a simple menu for icewm..."
check_and_backup "$HOME/.icewm"
check_and_create_directory "$HOME/.icewm"
xdg_menu --format icewm --fullmenu --root-menu "$PREFIX/etc/xdg/menus/termux-applications.menu" >~/.icewm/programs
fi
}
#########################################################################
#
# Theme Installer
#
#########################################################################
function set_config_dir() {
if [[ "$de_name" == "xfce" ]]; then
config_dirs=(autostart cairo-dock eww picom dconf gtk-3.0 Mousepad pulse Thunar menu ristretto rofi xfce4)
elif [[ "$de_name" == "lxqt" ]]; then
config_dirs=(fontconfig gtk-3.0 lxqt pcmanfm-qt QtProject.conf glib-2.0 Kvantum openbox qterminal.org)
elif [[ "$de_name" == "mate" ]]; then
config_dirs=(caja dconf galculator gtk-3.0 Kvantum lximage-qt menus Mousepad pavucontrol.ini xfce4)
else
config_dirs=(dconf gedit Kvantum openbox pulse rofi xfce4 enchant gtk-3.0 mimeapps.list polybar QtProject.conf Thunar)
fi
}
function ext_wall_setup() {
banner
if [[ "$ext_wall_answer" == "n" ]]; then
print_msg "${C}Skipping Extra Wallpapers Setup..."
echo
elif [[ "$ext_wall_answer" == "y" ]]; then
# if we doesn't set this to only run when CALL_FROM_CHANGE_STYLE == false then it will clone the wallpapers each time user run --change style
if [[ "$CALL_FROM_CHANGE_STYLE" == false ]]; then
print_msg "${BOLD}Installing Some Extra Wallpapers..."
echo
check_and_create_directory "$PREFIX/share/backgrounds"
# download_and_extract "https://archive.org/download/wallpaper-extra.tar/wallpaper-extra.tar.gz" "$PREFIX/share/backgrounds/"
cd "${HOME}" || exit 1
git clone --recursive --depth=1 -j "$(nproc)" https://github.com/JaKooLit/Wallpaper-Bank
cd Wallpaper-Bank/wallpapers/ || exit 1
mv Dynamic-Wallpapers/* "$PREFIX/share/backgrounds/"
check_and_delete "Dynamic-Wallpapers"
mv ./* "$PREFIX/share/backgrounds/"
cd "${HOME}" || exit 1
check_and_delete "Wallpaper-Bank"
fi
fi
print_to_config "ext_wall_answer"
}
function theme_installer() {
log_debug "Starting theme installation" "Theme: $style_name"
banner
print_msg "${BOLD}Configuring Theme: ${C}${style_name}"
echo
package_install_and_check "gnome-themes-extra gtk2-engines-murrine"
sleep 3
banner
print_msg "${BOLD}Configuring Wallpapers..."
echo
check_and_create_directory "$PREFIX/share/backgrounds"
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/wallpaper.tar.gz" "$PREFIX/share/backgrounds/"
banner
print_msg "${BOLD}Configuring Icon Pack..."
echo
package_install_and_check "gdk-pixbuf"
if [[ -z "$icons_folder" ]]; then
icons_folder="$HOME/.icons"
fi
check_and_create_directory "$icons_folder"
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/icon.tar.gz" "$icons_folder"
if [[ "$de_name" == "xfce" ]]; then
local icons_themes_names
icons_themes_names=$(ls "$icons_folder")
local icons_theme
for icons_theme in $icons_themes_names; do
if [[ -d "$icons_folder/$icons_theme" ]]; then
print_msg "Creating icon cache..."
gtk-update-icon-cache -f -t "$icons_folder/$icons_theme"
fi
done
fi
local sys_icons_themes_names
sys_icons_themes_names=$(ls "$PREFIX/share/icons")
local sys_icons_theme
for sys_icons_theme in $sys_icons_themes_names; do
if [[ -d "$sys_icons_folder/$sys_icons_theme" ]]; then
print_msg "Creating icon cache..."
gtk-update-icon-cache -f -t "$sys_icons_folder/$sys_icons_theme"
fi
done
print_msg "${BOLD}Installing Theme..."
echo
if [[ -z "$themes_folder" ]]; then
themes_folder="$HOME/.themes"
fi
check_and_create_directory "$themes_folder"
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/theme.tar.gz" "$themes_folder"
if [[ -d "$HOME/.config" ]] || [[ -d "$HOME/.local" ]]; then
print_msg "Creating backup of old config..."
must_back_folders=("$HOME/.config")
if [[ -d "$HOME/.local" ]]; then
must_back_folders+=("$HOME/.local")
fi
tar -cJvf "$HOME/old-config-$(date +%Y%m%d-%H%M%S).tar.xz" --warning=no-file-removed "${must_back_folders[@]}"
fi
print_msg "Applying Custom Configuration..."
echo
check_and_create_directory "$HOME/.config"
set_config_dir
for the_config_dir in "${config_dirs[@]}"; do
check_and_delete "$HOME/.config/$the_config_dir"
done
if [[ "$de_name" == "openbox" ]]; then
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/config.tar.gz" "$HOME"
else
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/config.tar.gz" "$HOME/.config/"
fi
}
#########################################################################
#
# Install Additional Packages For Setup
#
#########################################################################
function additional_required_steps() {
banner
if [[ "$de_name" == "xfce" ]]; then
print_msg "${BOLD} Installing Additional Packages If Required...${NC}"
echo
if [[ "$style_answer" == "4" ]] || [[ "$style_answer" == "5" ]]; then
install_font_for_style "${style_answer}"
fi
if [[ "$style_answer" == "5" ]] || [[ "$style_answer" == "6" ]]; then
package_install_and_check "eww"
fi
if [[ "$style_answer" == "6" ]]; then
package_install_and_check "rofi"
fi
if [[ "$style_answer" == "3" ]]; then
package_install_and_check "xdotool"
fi
elif [[ "$de_name" == "openbox" ]]; then
if [[ "$style_answer" == "1" ]]; then
package_install_and_check "xfce4-settings mpd thunar"
install_font_for_style "1"
elif [[ "$style_answer" == "2" ]]; then
package_install_and_check "devilspie2 xfce4-terminal thunar dunst python python3 tint2 xdotool"
install_font_for_style "2"
print_msg "${BOLD}Installing package: ${C}pywal"
pip install pywal
print_msg "${BOLD}Installing package: ${C}pyyaml"
pip install pyyaml
print_msg "${BOLD}Installing package: ${C}pyxdg"
pip install pyxdg
print_msg "${BOLD}Installing package: ${C}docopt"
pip install docopt
print_msg "${BOLD}Installing package: ${C}rofimoji"
pip install rofimoji
fi
fi
}
#########################################################################
#
# Setup Selected Style And Wallpapers / setup config
#
#########################################################################
function setup_config() {
cd "$HOME" || return
if [[ ${style_answer} =~ ^[1-9][0-9]*$ ]]; then
banner
print_msg "${BOLD}Installing $de_name Style: ${C}${style_answer}"
theme_installer
additional_required_steps
print_to_config "style_answer"
else
print_failed "Failed to select style..."
fi
}
#########################################################################
#
# Setup required permissions
#
#########################################################################
function setup_folder() {
banner
print_msg "${BOLD}Configuring Storage..."
echo
while true; do
termux-setup-storage
sleep 4
if [[ -d ~/storage ]]; then
print_success "Storage configured successfully"
break
else
print_failed "Storage permission denied"
fi
sleep 3
done
cd "$HOME" || return
termux-reload-settings
directories=(Music Pictures Videos)
for dir in "${directories[@]}"; do
check_and_create_directory "/sdcard/$dir"
done
check_and_create_directory "$HOME/Desktop"
ln -s "$HOME/storage/shared/Music" "$HOME/"
ln -s "$HOME/storage/shared/Pictures" "$HOME/"
ln -s "$HOME/storage/shared/Videos" "$HOME/"
}
function setup_mic_permission() {
if [[ "$IS_TERMUX_API_INSTALLED" == true ]]; then
print_msg "Setting up mic permission..."
echo
print_msg "Please grant mic permission"
echo
sleep 2
termux-microphone-record -l 1 -f /dev/null >/dev/null 2>&1 &
sleep 5
else
print_msg "You can't use microphone because you didn't install Termux-Api apk"
sleep 3
fi
}
function setup_necessary_permissions() {
setup_folder
setup_mic_permission
}
#########################################################################
#
# Hardware Acceleration Setup
#
#########################################################################
# setup hardware acceleration, check if the enable-hw-acceleration already exist, if then first check if it different from github , then ask user if they want to replace it with the latest or not, if not then continue with the local enable-hw-acceleration file
function get_hw_acceleration_source() {
local script_path="${current_path}/enable-hw-acceleration"
local remote_url="https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/enable-hw-acceleration"
if [[ -f "$script_path" ]]; then
local current_script_hash
current_script_hash=$(curl -sL "$remote_url" | sha256sum | cut -d ' ' -f 1)
# Add error checking for remote fetch
if [[ -z "$current_script_hash" ]]; then
print_msg "Failed to fetch remote script for comparison. Using local version."
chmod +x "$script_path"
return
fi
local local_script_hash
local_script_hash=$(sha256sum "$script_path" | cut -d ' ' -f 1)
if [[ "$local_script_hash" != "$current_script_hash" ]]; then
print_msg "A different version of the hardware acceleration installer is detected."
echo
confirmation_y_or_n "Do you want to replace it with the latest version?" change_old_hw_installer
if [[ "$change_old_hw_installer" == "y" ]]; then
check_and_backup "$script_path"
download_file "$script_path" "$remote_url"
else
print_msg "Using the local hardware acceleration setup file."
fi
print_to_config "change_old_hw_installer"
else
print_msg "Using the local hardware acceleration setup file."
fi
else
download_file "$script_path" "$remote_url"
fi
chmod +x "$script_path"
}
function hw_config() {
banner
print_msg "${BOLD}Configuring Hardware Acceleration"
echo
print_to_config "enable_hw_acc"
# Get the hardware acceleration source
get_hw_acceleration_source
# Source the script
# shellcheck disable=SC1091
source "${current_path}/enable-hw-acceleration"
# Call the main hardware acceleration setup function
run_hw_acceleration_setup_main
# Clean up
check_and_delete "${current_path}/enable-hw-acceleration"
log_debug "$current_path $current_script_hash $local_script_hash"
}
#########################################################################
#
# Proot Distro Setup
#
#########################################################################
# same as the hardware acceleration setup but for distro-container-setup file
function get_distro_container_source() {
local script_path="${current_path}/distro-container-setup"
local remote_url="https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/distro-container-setup"
if [[ -f "$script_path" ]]; then
local current_script_hash
current_script_hash=$(curl -sL "$remote_url" | sha256sum | cut -d ' ' -f 1)
local local_script_hash
local_script_hash=$(sha256sum "$script_path" | cut -d ' ' -f 1)
if [[ "$local_script_hash" != "$current_script_hash" ]]; then
print_msg "It looks like you already have a different distro-container setup script in your current directory"
echo
confirmation_y_or_n "Do you want to change it with the latest installer" change_old_distro_installer
if [[ "$change_old_distro_installer" == "y" ]]; then
check_and_backup "$script_path"
download_file "$script_path" "$remote_url"
else
print_msg "Using the local distro-container setup file"
fi
print_to_config "change_old_distro_installer"
else
print_msg "Using the local distro-container setup file"
fi
else
download_file "$script_path" "$remote_url"
fi
chmod +x "$script_path"
}
function distro_container_setup() {
print_to_config "distro_add_answer"
if [[ "$distro_add_answer" == "n" ]]; then
banner
print_msg "${C}Skipping Linux Distro Container Setup..."
echo
if [[ "$enable_hw_acc" == "y" ]]; then
hw_config
else
print_to_config "enable_hw_acc"
fi
else
banner
print_msg "${BOLD}Configuring Linux Distro Container"
echo
# Get the distro container source
get_distro_container_source
# Source the script
# shellcheck disable=SC1091
source "${current_path}/distro-container-setup"
# Call the main distro container setup function
run_distro_container_setup_main
# Clean up
check_and_delete "${current_path}/distro-container-setup"
fi
log_debug "$current_path $distro_add_answer $local_script_hash"
}
#########################################################################
#
# Vnc | Termux:x11 | Launch Scripts
#
#########################################################################
function setup_vncstart_cmd() {
check_and_delete "$PREFIX/bin/vncstart"
if [[ "$enable_hw_acc" == "n" ]]; then
cat <"$PREFIX/bin/vncstart"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "vncstart command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
termux-wake-lock
# Prevent script from looping by checking if it's already running
if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
if pgrep -f "vncserver" >/dev/null; then
echo "[!] vncserver is already running. Exiting."
exit 1
fi
fi
vnc_server_pid=\$(pgrep -f "vncserver")
de_pid=\$(pgrep -f "$de_startup")
if [[ -n "\$de_pid" || -n "\$vnc_server_pid" ]]; then
vncstop -f
fi
if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
if \$use_debug; then
rm -rf ~/.config/pulse/*-runtime/pid
else
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
fi
pulseaudio --start --exit-idle-time=-1
pactl load-module module-sles-source > /dev/null 2>&1
fi
function show_vncstart_help() {
echo -e "\nUsage:\n"
echo "vncstart to start vncserver"
echo "vncstart --help to show help"
}
case \$1 in
--help|-h)
show_vncstart_help
;;
*)
if [[ -n "\$1" ]]; then
echo "[☓] Invalid option: \$1"
show_vncstart_help
else
env XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg vncserver
fi
;;
esac
EOF
elif [[ "$enable_hw_acc" == "y" ]]; then
cat <"$PREFIX/bin/vncstart"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "vncstart command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
termux-wake-lock
# Prevent script from looping by checking if it's already running
if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
if pgrep -f "vncserver" >/dev/null; then
echo "[!] vncserver is already running. Exiting."
exit 1
fi
fi
vnc_server_pid=\$(pgrep -f "vncserver")
de_pid=\$(pgrep -f "$de_startup")
if [[ -n "\$de_pid" || -n "\$vnc_server_pid" ]]; then
vncstop -f
fi
if [[ "\$1" != "--help" && "\$1" != "-h" ]]; then
if \$use_debug; then
rm -rf ~/.config/pulse/*-runtime/pid
else
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
fi
pulseaudio --start --exit-idle-time=-1
pactl load-module module-sles-source > /dev/null 2>&1
fi
function show_vncstart_help() {
echo -e "\nUsage:\n"
echo "vncstart to start vncserver with GPU acceleration"
echo "vncstart --nogpu to start vncserver without GPU acceleration"
echo "vncstart --help to show this help message"
}
case \$1 in
--nogpu)
env XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe vncserver
;;
--help|-h)
show_vncstart_help
;;
*)
if [[ -n "\$1" ]]; then
echo "[☓] Invalid option: \$1"
show_vncstart_help
else
export ${set_to_export}
${initialize_server_method} &
env XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg $hw_method vncserver
fi
;;
esac
EOF
fi
chmod +x "$PREFIX/bin/vncstart"
}
function setup_vncstop_cmd() {
check_and_delete "$PREFIX/bin/vncstop"
cat <<'EOF' >"$PREFIX/bin/vncstop"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=$(grep TracerPid "/proc/$$/status" | cut -d $'\t' -f 2)
if [ "$TRACER_PID" != 0 ]; then
TRACER_NAME=$(grep Name "/proc/${TRACER_PID}/status" | cut -d $'\t' -f 2)
if [ "$TRACER_NAME" = "proot" ]; then
msg
print_failed "vncstop command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
termux-wake-unlock
if [[ "$1" == "-f" ]] || [[ "$1" == "--force" ]]; then
pkill -9 Xtigervnc > /dev/null 2>&1
elif [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
echo -e "
vncstop to stop vncserver
vncstop --force to force stop vncserver
vncstop --help to show the helps
"
else
display_numbers=$(vncserver -list | awk '/^:[0-9]+/ {print $1}')
for display in $display_numbers; do
vncserver -kill "$display"
done
fi
rm $HOME/.vnc/localhost:*.log > /dev/null 2>&1
rm $PREFIX/tmp/.X1-lock > /dev/null 2>&1
rm $PREFIX/tmp/.X11-unix/X1 > /dev/null 2>&1
EOF
chmod +x "$PREFIX/bin/vncstop"
}
function setup_vnc() {
banner
print_msg "${BOLD}Configuring Vnc..."
echo
package_install_and_check "tigervnc"
check_and_create_directory "$HOME/.vnc"
check_and_delete "$HOME/.vnc/xstartup"
cat <"$HOME/.vnc/xstartup"
$de_startup &
EOF
chmod +x "$HOME/.vnc/xstartup"
setup_vncstart_cmd
setup_vncstop_cmd
}
function setup_tx11start_cmd() {
check_and_delete "$PREFIX/bin/tx11start"
if [[ "$enable_hw_acc" == "y" ]]; then
cat <"$PREFIX/bin/tx11start"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "tx11start command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
# Initialize flags
use_nogpu=false
use_nodbus=false
use_legacy=false
use_debug=false
de_startup="$de_startup"
# Function to show help
function show_tx11start_help() {
echo -e "
tx11start - Start Termux:X11 with GPU acceleration
tx11start --nogpu - Start without GPU acceleration
tx11start --nodbus - Start without dbus
tx11start --legacy - Start with -legacy-drawing
tx11start --debug - Show debug log
tx11start --xstartup "xstartup-name" - Launch another desktop environment
"
exit 0
}
# Parse arguments
while ((\$# >= 1)); do
case "\$1" in
--help)
show_tx11start_help
;;
--xstartup | -xstartup)
shift
de_startup="\$1"
echo "\$de_startup" > "$HOME/.xstartup"
;;
--nogpu | --no-gpu)
use_nogpu=true
;;
--nodbus | --no-dbus)
use_nodbus=true
;;
--legacy)
use_legacy=true
;;
--debug)
use_debug=true
;;
*)
echo "Invalid option: \$1"
show_tx11start_help
;;
esac
shift
done
# Kill existing Termux X11 processes
pkill -f com.termux.x11 >/dev/null 2>&1
pkill -9 "\$de_startup" >/dev/null 2>&1
# Ensure XDG_RUNTIME_DIR exists
export XDG_RUNTIME_DIR=/data/data/com.termux/files/usr/tmp
mkdir -p "\$XDG_RUNTIME_DIR"
# Export DISPLAY variable
export DISPLAY=:${display_number}
# Start pulseaudio unless --help was given
if [[ "\$1" != "--help" ]]; then
termux-wake-lock
if \$use_debug; then
rm -rf ~/.config/pulse/*-runtime/pid
else
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
fi
# pulseaudio --start --load="module-aaudio-sink" --exit-idle-time=-1
pulseaudio --start --exit-idle-time=-1
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
if \$use_debug; then
pactl load-module module-sles-source
else
pactl load-module module-sles-source >/dev/null 2>&1
fi
fi
# Set environment variables if NOT using --nogpu
if ! \$use_nogpu; then
export ${set_to_export}
if \$use_debug; then
${initialize_server_method} &
else
${initialize_server_method} >/dev/null 2>&1 &
fi
export ${gpu_environment_variable} ${hw_method}
else
export LIBGL_ALWAYS_SOFTWARE=1 MESA_LOADER_DRIVER_OVERRIDE=llvmpipe GALLIUM_DRIVER=llvmpipe
fi
sleep 1
# Construct X11 command
# x11_cmd="XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR} termux-x11 :0" # Comment this because i found that the sound doesn't working if i set this XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR}
if \$use_nogpu; then
x11_cmd="LIBGL_ALWAYS_SOFTWARE=1 termux-x11 :0"
else
x11_cmd="termux-x11 :0"
fi
if \$use_legacy; then
x11_cmd+=" -legacy-drawing"
fi
# Start X11
if \$use_debug; then
eval "\$x11_cmd" &
else
eval "\$x11_cmd" >/dev/null 2>&1 &
fi
sleep 1
# Start X11 Main Activity
if \$use_debug; then
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
else
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity >/dev/null 2>&1
fi
sleep 1
# Start the desktop environment
if \$use_nodbus; then
if \$use_debug; then
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg \$de_startup &
else
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg \$de_startup >/dev/null 2>&1 &
fi
else
if \$use_debug; then
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session \$de_startup &
else
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session \$de_startup >/dev/null 2>&1 &
fi
fi
EOF
elif [[ "$enable_hw_acc" == "n" ]]; then
cat <"$PREFIX/bin/tx11start"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "tx11start command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
# Initialize flags
use_nodbus=false
use_legacy=false
use_debug=false
de_startup="$de_startup"
# Function to show help
function show_tx11start_help() {
echo -e "
tx11start - Start Termux:X11
tx11start --nodbus - Start without dbus
tx11start --legacy - Start with -legacy-drawing
tx11start --debug - Show debug log
tx11start --xstartup "xstartup-name" - Launch another desktop environment
"
exit 0
}
# Parse arguments
while ((\$# >= 1)); do
case "\$1" in
--help)
show_tx11start_help
;;
--xstartup | -xstartup)
shift
de_startup="\$1"
echo "\$de_startup" > "$HOME/.xstartup"
;;
--nodbus | --no-dbus)
use_nodbus=true
;;
--legacy)
use_legacy=true
;;
--debug)
use_debug=true
;;
*)
echo "Invalid option: \$1"
show_tx11start_help
;;
esac
shift
done
# Kill existing Termux X11 processes
pkill -f com.termux.x11 >/dev/null 2>&1
pkill -9 "\$de_startup" >/dev/null 2>&1
# Ensure XDG_RUNTIME_DIR exists
export XDG_RUNTIME_DIR=/data/data/com.termux/files/usr/tmp
mkdir -p "\$XDG_RUNTIME_DIR"
# Export DISPLAY variable
export DISPLAY=:${display_number}
# Start pulseaudio unless --help was given
if [[ "\$1" != "--help" ]]; then
termux-wake-lock
if \$use_debug; then
rm -rf ~/.config/pulse/*-runtime/pid
else
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
fi
# pulseaudio --start --load="module-aaudio-sink" --exit-idle-time=-1
pulseaudio --start --exit-idle-time=-1
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
if \$use_debug; then
pactl load-module module-sles-source
else
pactl load-module module-sles-source >/dev/null 2>&1
fi
fi
# Construct X11 command
# x11_cmd="XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR} termux-x11 :0" # Comment this because i found that the sound doesn't working if i set this XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR}
x11_cmd="termux-x11 :0"
if \$use_legacy; then
x11_cmd+=" -legacy-drawing"
fi
# Start X11
if \$use_debug; then
eval "\$x11_cmd" &
else
eval "\$x11_cmd" >/dev/null 2>&1 &
fi
sleep 1
# Start X11 Main Activity
if \$use_debug; then
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
else
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity >/dev/null 2>&1
fi
sleep 1
# Start the desktop environment
if \$use_nodbus; then
if \$use_debug; then
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg \$de_startup &
else
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg \$de_startup >/dev/null 2>&1 &
fi
else
if \$use_debug; then
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session \$de_startup &
else
env DISPLAY=:${display_number} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session \$de_startup >/dev/null 2>&1 &
fi
fi
EOF
fi
if [[ "$de_name" == "xfce" ]]; then
cat <>"$PREFIX/bin/tx11start"
# Kill xfce4-screensaver if running
sleep 5
process_id=\$(ps aux | grep '[x]fce4-screensaver' | awk '{print \$2}')
if [[ -n "\$process_id" ]]; then
if \$use_debug; then
kill "\$process_id"
else
kill "\$process_id" > /dev/null 2>&1
fi
fi
EOF
fi
chmod +x "$PREFIX/bin/tx11start"
}
function setup_tx11stop_cmd() {
check_and_delete "$PREFIX/bin/tx11stop"
if [[ "$de_name" == "openbox" ]]; then
cat <"$PREFIX/bin/tx11stop"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "tx11stop command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
termux-wake-unlock
if [[ -f "$HOME/.xstartup" ]]; then
de_startup=\$(cat "$HOME/.xstartup")
else
de_startup="$de_startup"
fi
termux_x11_pid=\$(pgrep -f "/system/bin/app_process / com.termux.x11.Loader :${display_number}")
de_pid=\$(pgrep -f \$de_startup)
if [[ -n "\$termux_x11_pid" ]] || [[ -n "\$de_pid" ]]; then
kill -9 "\$termux_x11_pid" > /dev/null 2>&1
pkill -9 pulseaudio > /dev/null 2>&1
killall virgl_test_server > /dev/null 2>&1
pkill -9 openbox* > /dev/null 2>&1
pkill -9 dbus-* > /dev/null 2>&1
pkill -f com.termux.x11 > /dev/null 2>&1
sleep 1
if [[ ! -n "\$termux_x11_pid" ]] || [[ ! -n "\$de_pid" ]]; then
echo -e "${G}Termux:X11 Stopped Successfully ${NC}"
[[ -f "$HOME/.xstartup" ]] && rm -rf "$HOME/.xstartup"
fi
elif [[ "\$1" == "-f" ]] || [[ "\$1" == "--force" ]]; then
pkill -f com.termux.x11 > /dev/null 2>&1
pkill -9 openbox* > /dev/null 2>&1
killall virgl_test_server > /dev/null 2>&1
pkill -9 pulseaudio > /dev/null 2>&1
pkill -9 dbus-* > /dev/null 2>&1
echo -e "${G}Termux:X11 Successfully Force Stopped ${NC}"
[[ -f "$HOME/.xstartup" ]] && rm -rf "$HOME/.xstartup"
elif [[ "\$1" == "-h" ]]; then
echo -e "tx11stop to stop termux:x11"
echo -e "tx11stop -f to kill termux:x11"
fi
exec 2>/dev/null
EOF
else
cat <"$PREFIX/bin/tx11stop"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=\$(grep TracerPid "/proc/\$\$/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_PID" != 0 ]; then
TRACER_NAME=\$(grep Name "/proc/\${TRACER_PID}/status" | cut -d \$'\t' -f 2)
if [ "\$TRACER_NAME" = "proot" ]; then
msg
print_failed "tx11stop command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
termux-wake-unlock
if [[ -f "$HOME/.xstartup" ]]; then
de_startup=\$(cat "$HOME/.xstartup")
else
de_startup="$de_startup"
fi
termux_x11_pid=\$(pgrep -f "/system/bin/app_process / com.termux.x11.Loader :${display_number}")
de_pid=\$(pgrep -f \$de_startup)
if [[ -n "\$termux_x11_pid" ]] || [[ -n "\$de_pid" ]]; then
kill -9 "\$termux_x11_pid" > /dev/null 2>&1
pkill -9 pulseaudio > /dev/null 2>&1
killall virgl_test_server > /dev/null 2>&1
pkill -9 $de_name-* > /dev/null 2>&1
pkill -9 dbus-* > /dev/null 2>&1
pkill -f com.termux.x11 > /dev/null 2>&1
if [[ ! -n "\$termux_x11_pid" ]] || [[ ! -n "\$de_pid" ]]; then
echo -e "${G}Termux:X11 Stopped Successfully ${NC}"
[[ -f "$HOME/.xstartup" ]] && rm -rf "$HOME/.xstartup"
fi
elif [[ "\$1" == "-f" ]] || [[ "\$1" == "--force" ]]; then
pkill -f com.termux.x11 > /dev/null 2>&1
pkill -9 $de_name-* > /dev/null 2>&1
killall virgl_test_server > /dev/null 2>&1
pkill -9 pulseaudio > /dev/null 2>&1
pkill -9 dbus-* > /dev/null 2>&1
echo -e "${G}Termux:X11 Successfully Force Stopped ${NC}"
[[ -f "$HOME/.xstartup" ]] && rm -rf "$HOME/.xstartup"
elif [[ "\$1" == "-h" ]]; then
echo -e "tx11stop to stop termux:x11"
echo -e "tx11stop -f to kill termux:x11"
fi
exec 2>/dev/null
EOF
fi
chmod +x "$PREFIX/bin/tx11stop"
}
function setup_termux_x11() {
banner
print_msg "${BOLD}Configuring Termux:X11"
echo
package_install_and_check "termux-x11-nightly"
local repo_owner="termux"
local repo_name="termux-x11"
local latest_termux_x11_tag
latest_termux_x11_tag=$(get_latest_release "termux" "termux-x11")
local termux_x11_url="https://github.com/$repo_owner/$repo_name/releases/download/$latest_termux_x11_tag/"
local assets
assets=$(curl -s "https://api.github.com/repos/$repo_owner/$repo_name/releases/latest" | grep -oP '(?<="name": ")[^"]*')
deb_assets=$(echo "$assets" | grep "termux-x11.*all.deb")
download_file "$current_path/termux-x11.deb" "$termux_x11_url/$deb_assets"
apt install "$current_path/termux-x11.deb" -y
rm "$current_path/termux-x11.deb"
# "sed -i '12s/^#//' "$HOME/.termux/termux.properties"
setup_tx11start_cmd
setup_tx11stop_cmd
}
function gui_termux_x11() {
cat <<'EOF' >"$PREFIX/bin/gui"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=$(grep TracerPid "/proc/\$\$/status" | cut -d $'\t' -f 2)
if [ "$TRACER_PID" != 0 ]; then
TRACER_NAME=$(grep Name "/proc/${TRACER_PID}/status" | cut -d $'\t' -f 2)
if [ "$TRACER_NAME" = "proot" ]; then
msg
print_failed "gui command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
forward_display() {
echo "${R}[${C}-${R}]${G} Starting display on: ${given_ip}:${display_port} ${NC}"
pkill -9 "$de_startup" >/dev/null 2>&1
pulseaudio --start --exit-idle-time=-1
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
pactl load-module module-sles-source >/dev/null 2>&1
export XDG_RUNTIME_DIR=/data/data/com.termux/files/usr/tmp
mkdir -p "$XDG_RUNTIME_DIR"
env DISPLAY=${given_ip}:${display_port} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session $de_startup
}
case $1 in
--start | -l)
tx11start
;;
--display | -d)
if [[ "$2" == *":"* ]]; then
# Everything before the last colon
given_ip="${2%:*}"
# Everything after the last colon
display_port="${2##*:}"
else
given_ip="$2"
display_port="0"
fi
if [ -z "$given_ip" ]; then
print_failed "No IP address provided"
echo -e "Usage: gui --display [:]\nExamples:\n gui --display 192.168.1.100:0\n gui --display 192.168.1.100"
exit 1
fi
forward_display
unset given_ip display_port
;;
--stop | -s)
tx11stop
;;
--kill | -k | -kill)
tx11stop -f
print_success "gui services killed successfully"
;;
--help | -h)
echo -e "gui --start / gui -l to start termux:x11"
echo -e "gui --display / gui -d to forward display to IP address"
echo -e "gui --stop / gui -s to stop termux:x11"
echo -e "gui --kill / gui -k to kill gui services"
;;
*)
echo "${R}Invalid choise${NC}"
gui -h
;;
esac
EOF
}
function gui_both() {
cat <<'EOF' >"$PREFIX/bin/gui"
#!/data/data/com.termux/files/usr/bin/bash
source /data/data/com.termux/files/usr/etc/termux-desktop/common_functions
# This code block is taken from:- https://github.com/termux/proot-distro/blob/master/proot-distro.sh#L172C1-L184C1
TRACER_PID=$(grep TracerPid "/proc/\$\$/status" | cut -d $'\t' -f 2)
if [ "$TRACER_PID" != 0 ]; then
TRACER_NAME=$(grep Name "/proc/${TRACER_PID}/status" | cut -d $'\t' -f 2)
if [ "$TRACER_NAME" = "proot" ]; then
msg
print_failed "gui command should not be executed under PRoot.\${W}"
msg
exit 1
fi
unset TRACER_NAME
fi
unset TRACER_PID
forward_display() {
echo "${R}[${C}-${R}]${G} Starting display on: ${given_ip}:${display_port} ${NC}"
pkill -9 "$de_startup" >/dev/null 2>&1
pulseaudio --start --exit-idle-time=-1
pacmd load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1
rm -rf ~/.config/pulse/*-runtime/pid >/dev/null 2>&1
pactl load-module module-sles-source >/dev/null 2>&1
export XDG_RUNTIME_DIR=/data/data/com.termux/files/usr/tmp
mkdir -p "$XDG_RUNTIME_DIR"
env DISPLAY=${given_ip}:${display_port} XDG_CONFIG_DIRS=/data/data/com.termux/files/usr/etc/xdg dbus-launch --exit-with-session $de_startup &
}
case $1 in
--start | -l)
case $2 in
tx11)
tx11start
;;
vnc)
vncstart
;;
*)
echo -e "${R}Invalid choise. Use ${C}tx11${R} or ${C}vnc ${G}with it${NC}"
;;
esac
;;
--display | -d)
if [[ "$2" == *":"* ]]; then
# Everything before the last colon
given_ip="${2%:*}"
# Everything after the last colon
display_port="${2##*:}"
else
given_ip="$2"
display_port="0"
fi
if [ -z "$given_ip" ]; then
print_failed "No IP address provided"
echo -e "Usage: gui --display [:]\nExamples:\n gui --display 192.168.1.100:0\n gui --display 192.168.1.100"
exit 1
fi
forward_display
unset given_ip display_port
;;
--kill | -k | -kill)
vncstop -f >/dev/null 2>&1
tx11stop -f >/dev/null 2>&1
print_success "gui services killed successfully"
;;
--stop | -s)
case $2 in
tx11)
tx11stop
;;
vnc)
vncstop
;;
*)
echo -e "${R}Invalid choise. Use ${C}tx11${R} or ${C}vnc ${G}with it${NC}"
;;
esac
;;
--help | -h)
echo -e "Usage: gui [OPTION] [ARGUMENT]\n"
echo -e "Options:"
echo -e " --start, -l [tx11/vnc] Start a GUI (termux:x11 or VNC)"
echo -e " --display, -d Forward display to IP address"
echo -e " --stop, -s [tx11/vnc] Stop a GUI (termux:x11 or VNC)"
echo -e " --kill, -k Kill both GUI services at once"
echo -e " --help, -h Show this help message"
;;
*)
echo -e "${R}Invalid choice${NC}"
gui -h
;;
esac
EOF
}
function gui_launcher() {
check_and_delete "$PREFIX/bin/gui"
package_install_and_check "xorg-xhost"
if [[ "$gui_mode" == "termux_x11" ]]; then
setup_termux_x11
gui_termux_x11
elif [[ "$gui_mode" == "both" ]]; then
setup_termux_x11
setup_vnc
gui_both
else
setup_termux_x11
gui_termux_x11
fi
print_to_config "gui_mode"
print_to_config "display_number"
chmod +x "$PREFIX/bin/gui"
check_and_create_directory "$PREFIX/share/applications/"
cat <"$PREFIX/share/applications/killgui.desktop"
[Desktop Entry]
Version=1.0
Type=Application
Name=Stop Desktop
Comment=Kill or stop termux desktop
Exec=gui --kill
Icon=system-shutdown
Categories=System;
Path=
Terminal=false
StartupNotify=false
EOF
chmod 644 "$PREFIX/share/applications/killgui.desktop"
cp "$PREFIX/share/applications/killgui.desktop" "$HOME/Desktop/"
}
function check_desktop_process() {
banner
print_msg "Checking Termux:X11 and $de_name setup or not..."
echo
sleep 0.5
# check tx11start file and start termux x11 to check termux x11 process
if [[ -f "${PREFIX}/bin/tx11start" ]]; then
print_success "Found tx11start file."
print_msg "Starting Termux:X11 for checkup..."
termux-x11 :"${display_number}" -xstartup xfce4-session >/dev/null 2>&1 &
sleep 10
log_debug "$(cat "$PREFIX/bin/tx11start")"
termux-reload-settings
local termux_x11_pid
termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
if [[ -n "$termux_x11_pid" ]]; then
print_success "Termux:X11 Working"
else
print_failed "No Termux:X11 process found"
fi
# check for the desktop environment related process
local de_pid
case "$de_name" in
xfce)
de_pid="$(pgrep xfce4)"
;;
lxqt)
de_pid="$(pgrep -f "lxqt-session|lxqt-panel")"
;;
openbox)
de_pid="$(pgrep -f "openbox|openbox-session")"
;;
mate)
de_pid="$(pgrep -f "mate-session|mate-panel")"
;;
i3)
de_pid="$(pgrep -f "i3|i3-with-shmlog")"
;;
dwm)
de_pid="$(pgrep dwm)"
;;
bspwm)
de_pid="$(pgrep bspwm)"
;;
awesome)
de_pid="$(pgrep -f awesome)"
;;
fluxbox)
de_pid="$(pgrep -f fluxbox)"
;;
*)
print_failed "Unknown desktop environment: $de_name"
sleep 0.2
return 1
;;
esac
if [[ -n "$de_pid" ]]; then
print_success "$de_name is running fine"
sleep 0.2
else
print_failed "No $de_name process found, attempting to reinstall..."
sleep 0.2
install_desktop
# Check again after installation
unset de_pid
case "$de_name" in
xfce)
de_pid="$(pgrep xfce4)"
;;
lxqt)
de_pid="$(pgrep -f "lxqt-session|lxqt-panel|pcmanfm-qt")"
;;
openbox)
de_pid="$(pgrep -f "openbox|openbox-session")"
;;
mate)
de_pid="$(pgrep -f "mate-session|mate-panel|caja")"
;;
i3)
de_pid="$(pgrep -f "i3|i3-with-shmlog")"
;;
dwm)
de_pid="$(pgrep dwm)"
;;
bspwm)
de_pid="$(pgrep bspwm)"
;;
awesome)
de_pid="$(pgrep -f awesome)"
;;
fluxbox)
de_pid="$(pgrep -f fluxbox)"
;;
*)
print_failed "Unknown desktop environment: $de_name"
sleep 0.2
return 1
;;
esac
if [[ -n "$de_pid" ]]; then
print_success "$de_name is now running after re-installation"
sleep 0.2
else
print_failed "$de_name failed to install or start, still after re-installation"
sleep 0.2
return 1
fi
fi
# check tx11stop file and run it to check if there any termux x11 process exist or not
if [[ -f "${PREFIX}/bin/tx11stop" ]]; then
print_success "Found tx11stop file."
log_debug "$(cat "$PREFIX/bin/tx11stop")"
tx11stop -f
# Wait a bit for the process to stop
sleep 2
unset termux_x11_pid
termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
if [[ -z "$termux_x11_pid" ]]; then
print_success "Tx11stop command working"
else
print_failed "Tx11stop command not working"
fi
fi
fi
print_msg "Backing up current Termux:x11 preferences..."
echo
termux-x11 &
termux-x11-preference list >"$HOME/old-termx-x11-preferences"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termx-x11-preferences"
print_msg "Adding custom Termux:x11 preferences..."
echo
termux-x11-preference /dev/null 2>&1
check_and_delete "termx-x11-preferences"
}
#########################################################################
#
# Install Browser
#
#########################################################################
function browser_installer() {
banner
print_to_config "installed_browser"
if [[ ${installed_browser} == "firefox" ]]; then
package_install_and_check "firefox"
elif [[ ${installed_browser} == "chromium" ]]; then
package_install_and_check "chromium"
elif [[ ${installed_browser} == "all" ]]; then
package_install_and_check "firefox chromium"
elif [[ ${installed_browser} == "skip" ]]; then
print_msg "${C}Skipping Browser Installation..."
echo
sleep 2
else
package_install_and_check "firefox"
print_to_config "installed_browser" "firefox"
fi
}
#########################################################################
#
# Install Ide
#
#########################################################################
function ide_installer() {
banner
print_to_config "installed_ide"
if [[ ${installed_ide} == "code" ]]; then
package_install_and_check "code-oss code-is-code-oss"
elif [[ ${installed_ide} == "geany" ]]; then
package_install_and_check "geany"
elif [[ ${installed_ide} == "neovim" ]]; then
package_install_and_check "neovim lua51 lua-language-server stylua"
package_install_and_check "tree-sitter-*"
check_and_backup "$HOME/.config/nvim"
if [[ "$installed_nvim_distro" == "nvchad" ]]; then
git clone https://github.com/NvChad/starter ~/.config/nvim
elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
git clone https://github.com/LazyVim/starter ~/.config/nvim
elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
git clone https://github.com/sabamdarif/mynvim.git ~/.config/nvim
fi
print_to_config "installed_nvim_distro"
check_and_delete "$HOME/.config/nvim/.git"
elif [[ ${installed_ide} == "all" ]]; then
package_install_and_check "code-oss code-is-code-oss geany neovim lua51 lua-language-server stylua"
package_install_and_check "tree-sitter-*"
check_and_backup "$HOME/.config/nvim"
if [[ "$installed_nvim_distro" == "nvchad" ]]; then
git clone https://github.com/NvChad/starter ~/.config/nvim
elif [[ "$installed_nvim_distro" == "lazyvim" ]]; then
git clone https://github.com/LazyVim/starter ~/.config/nvim
elif [[ "$installed_nvim_distro" == "mynvim" ]]; then
git clone https://github.com/sabamdarif/mynvim.git ~/.config/nvim
fi
print_to_config "installed_nvim_distro"
check_and_delete "$HOME/.config/nvim/.git"
elif [[ ${installed_ide} == "skip" ]]; then
print_msg "${C}Skipping Ide Installation..."
echo
sleep 2
else
package_install_and_check "code-oss code-is-code-oss"
fi
}
#########################################################################
#
# Install Media Player
#
#########################################################################
function media_player_installer() {
banner
print_to_config "installed_media_player"
if [[ ${installed_media_player} == "vlc" ]]; then
package_install_and_check "vlc-qt-static"
elif [[ ${installed_media_player} == "mpv" ]]; then
package_install_and_check "mpv"
elif [[ ${installed_media_player} == "all" ]]; then
package_install_and_check "vlc-qt-static mpv"
elif [[ ${installed_media_player} == "skip" ]]; then
print_msg "${C}Skipping Media Player Installation..."
echo
sleep 2
else
package_install_and_check "vlc-qt-static"
fi
}
#########################################################################
#
# Install Photo Editor
#
#########################################################################
function setup_gimp_plugins() {
package_install_and_check "gimp-resynthesizer"
### un-comment this if you want the bleeding edge version of resynthesizer
# download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/install-resynthesizer-termux"
# if [[ -f "install-resynthesizer-termux" ]]; then
# chmod +x install-resynthesizer-termux
# source install-resynthesizer-termux
# fi
}
function photo_editor_installer() {
banner
print_to_config "installed_photo_editor"
if [[ ${installed_photo_editor} == "gimp" ]]; then
package_install_and_check "gimp"
setup_gimp_plugins
elif [[ ${installed_photo_editor} == "inkscape" ]]; then
package_install_and_check "inkscape"
elif [[ ${installed_photo_editor} == "all" ]]; then
package_install_and_check "gimp inkscape"
setup_gimp_plugins
elif [[ ${installed_photo_editor} == "skip" ]]; then
print_msg "${C}Skipping Photo Editor Installation..."
echo
sleep 2
else
package_install_and_check "gimp"
fi
}
#########################################################################
#
# Install Software Manager
#
#########################################################################
function install_termux_desktop_appstore() {
banner
print_msg "${C}Setting up AppStore..."
echo
download_file "https://raw.githubusercontent.com/sabamdarif/Termux-AppStore/refs/heads/src/appstore"
chmod +x "appstore"
./appstore --install v0.5.4
cp "${PREFIX}/share/applications/org.sabamdarif.termux.appstore.desktop" "/data/data/com.termux/files/home/Desktop"
chmod +x /data/data/com.termux/files/home/Desktop/org.sabamdarif.termux.appstore.desktop
}
#########################################################################
#
# Setup shell bash / zsh
#
#########################################################################
function get_shellrc_path() {
if [[ -z "$shell_name" ]]; then
shell_name=$(basename "$SHELL")
fi
if [[ "$shell_name" == "bash" ]]; then
shell_rc_file="$HOME/.bashrc"
elif [[ "$shell_name" == "zsh" ]]; then
shell_rc_file="$HOME/.zshrc"
else
print_failed "Unable to get shellrc path"
exit 1
fi
}
function setup_zsh() {
banner
shell_name="zsh"
print_msg "${BOLD}Configuring zsh.."
package_install_and_check "zsh git"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/setup-zsh"
chmod +x setup-zsh
# shellcheck disable=SC1091
source setup-zsh
check_and_delete "setup-zsh"
if [[ -f "$HOME/.zshrc" ]]; then
print_success "zsh setup successfully"
fi
clear
print_to_config "selected_zsh_theme_name"
}
function setup_bash() {
banner
shell_name="bash"
print_msg "${BOLD}Configuring bash.."
package_install_and_check "git"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/setup-bash"
chmod +x setup-bash
# shellcheck disable=SC1091
source setup-bash
check_and_delete "setup-bash"
if [[ -f "$HOME/.bashrc" ]]; then
print_success "bash setup successfully"
fi
clear
}
function setup_shell() {
print_to_config "chosen_shell_name"
if [[ "$chosen_shell_name" == "zsh" ]]; then
setup_zsh
elif [[ "$chosen_shell_name" == "bash" ]] || [[ "$chosen_shell_name" == "bash_with_ble" ]]; then
setup_bash
fi
get_shellrc_path
}
function terminal_utility_setup() {
if [[ "$terminal_utility_setup_answer" == "n" ]]; then
banner
print_msg "${C}Skipping Terminal Utility Setup..."
echo
else
banner
print_msg "${C}${BOLD}Configuring Terminal Utility For Termux..."
echo
package_install_and_check "bat eza zoxide fastfetch openssh fzf"
if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
package_install_and_check "nala"
fi
check_and_backup "$PREFIX/etc/motd"
check_and_backup "$PREFIX/etc/motd-playstore"
check_and_backup "$PREFIX/etc/motd.sh"
download_file "$PREFIX/etc/motd.sh" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/motd.sh"
if grep -q "motd.sh$" "$PREFIX/etc/termux-login.sh"; then
sed -i "s|.*motd\.sh$|bash $PREFIX/etc/motd.sh|" "$PREFIX/etc/termux-login.sh"
else
echo "bash $PREFIX/etc/motd.sh" >>"$PREFIX/etc/termux-login.sh"
fi
check_and_create_directory "$HOME/.termux"
check_and_backup "$HOME/.termux/colors.properties $HOME/.termux/termux.properties $HOME/.aliases $HOME/.nanorc"
check_and_create_directory "$HOME/.config/fastfetch"
download_file "$HOME/.config/fastfetch/config.jsonc" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/config.jsonc"
download_file "$HOME/.termux/termux.properties" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termux.properties"
download_file "$HOME/.aliases" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/.aliases"
download_file "$HOME/.nanorc" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/.nanorc"
download_file "$HOME/.termux/colors.properties" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/colors.properties"
download_file "$PREFIX/bin/termux-ssh" "https://raw.githubusercontent.com/sabamdarif/simple-linux-scripts/main/termux-ssh" && chmod +x "$PREFIX/bin/termux-ssh"
download_file "$PREFIX/bin/termux-fastest-repo" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termux-fastest-repo"
chmod +x "$PREFIX/bin/termux-fastest-repo"
download_file "$PREFIX/bin/termux-color" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termux-color"
chmod +x "$PREFIX/bin/termux-color"
download_file "$PREFIX/bin/termux-nf" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/termux-nf"
chmod +x "$PREFIX/bin/termux-nf"
cp "$shell_rc_file" "${shell_rc_file}-2"
check_and_backup "$shell_rc_file"
mv "${shell_rc_file}-2" "${shell_rc_file}"
cat <>"$HOME/.shell_rc_content"
# set zoxide as cd
eval "\$(zoxide init --cmd cd ${shell_name})"
# FZF color scheme
export FZF_DEFAULT_OPTS=" \
--color=bg+:#363a4f,bg:#24273a,spinner:#f4dbd6,hl:#ed8796 \
--color=fg:#cad3f5,header:#ed8796,info:#c6a0f6,pointer:#f4dbd6 \
--color=marker:#b7bdf8,fg+:#cad3f5,prompt:#c6a0f6,hl+:#ed8796 \
--color=selected-bg:#494d64 \
--color=border:#363a4f,label:#cad3f5"
EOF
fi
cat <>"$HOME/.shell_rc_content"
# print your current termux-desktop configuration
alias 'tdconfig'='cat "$CONFIG_FILE"'
if [[ \$HOME != *termux* ]]; then
export DISPLAY=:$display_number
fi
EOF
if [[ "$distro_add_answer" == "y" ]]; then
cat <>"$HOME/.shell_rc_content"
# open the folder where all the apps added by proot-distro are located
alias 'pdapps'='cd /data/data/com.termux/files/usr/share/applications/pd_added && ls'
EOF
fi
if [[ "$PACKAGE_MANAGER" == "apt" ]]; then
cat <<'EOF' >>"$HOME/.shell_rc_content"
apt_wrapper() {
# First check if nala is actually installed. If not fall back to the apt
if ! command -v nala >/dev/null 2>&1; then
echo "nala not found, falling back to apt."
command apt "$@"
return $?
fi
# If no argument given then run nala to print help menu
if [ -z "$1" ]; then
command nala
return
fi
local cmd="$1"
shift
case "$cmd" in
install | in | add)
command nala install "$@"
;;
se* | sr | find)
command nala search "$@"
;;
up | update)
command nala update "$@"
;;
upg*)
command nala upgrade "$@"
;;
show | info)
command nala show "$@"
;;
cl*)
command nala clean "$@"
;;
ap | autopurge)
command nala autopurge "$@"
;;
un* | rem* | rm | del* | r)
command nala remove "$@"
;;
list-up*)
command nala list --upgradable
;;
*)
# pass the command ($cmd) along with the rest of the arguments
# although i don't think we need to pass $@
# but i still did it just to be in the safe side
command nala "$cmd" "$@"
;;
esac
}
alias apt='apt_wrapper'
EOF
fi
echo "[[ -f ${HOME}/.shell_rc_content ]] && source ${HOME}/.shell_rc_content" >>"${shell_rc_file}"
if [[ "$terminal_utility_setup_answer" == "y" ]]; then
echo "[[ -f ${HOME}/.aliases ]] && source ${HOME}/.aliases" >>"${shell_rc_file}"
fi
print_to_config "terminal_utility_setup_answer"
}
#########################################################################
#
# Setup File Manager Utility
#
#########################################################################
function install_fm_tools() {
if [[ "$fm_tools" == "y" ]]; then
banner
print_msg "${BOLD}Installing File Manager Tools..."
check_and_backup "$HOME/.local/share/nautilus/scripts"
check_and_create_directory "$HOME/.local/share/nautilus/scripts"
cd "$HOME" || exit 1
git clone -b termux https://github.com/sabamdarif/nautilus-scripts
cd nautilus-scripts || exit 1
bash setup-termux.sh
cd "$HOME" || exit 1
check_and_delete "nautilus-scripts"
fi
print_to_config "fm_tools"
}
#########################################################################
#
# Install Fonts
#
#########################################################################
function setup_fonts() {
banner
print_msg "${BOLD}Installing ${sel_base_name} Nerd Font..."
package_install_and_check "nerdfix fontconfig-utils"
check_and_create_directory "$HOME/.termux"
check_and_create_directory "$HOME/.fonts"
check_and_backup "$HOME/.termux/font.ttf"
if [[ -z "$latest_nf_version" ]]; then
latest_nf_version=$(get_latest_release "ryanoasis" "nerd-fonts")
fi
if [[ -z "$sel_asset_name" ]]; then
sel_base_name="0xProto"
fi
print_to_config "sel_base_name"
download_and_extract "https://github.com/ryanoasis/nerd-fonts/releases/download/${latest_nf_version}/${sel_base_name}.tar.xz" "$HOME/.fonts"
nerd_font_file=$(find "$HOME/.fonts" -type f \( -iname "${sel_base_name}*NerdFont-Regular.ttf" -o -iname "${sel_base_name}*NerdFont-Regular.otf" \) | head -n1)
if [[ -z "$nerd_font_file" ]]; then
nerd_font_file=$(find "$HOME/.fonts" -type f -iname "*NerdFont*" | head -n1)
fi
check_and_delete "$HOME/.fonts/README.md $HOME/.fonts/LICENSE"
if [[ -n "$nerd_font_file" ]]; then
cp "$nerd_font_file" "$HOME/.termux/font.ttf"
fc-cache -f
else
print_failed "Could not locate a NerdFont-Regular file for ${sel_base_name}."
exit 1
fi
}
#########################################################################
#
# Install Wine
#
#########################################################################
function run_wine_shortcut_script() {
print_success "Adding wine desktop shortcuts..."
download_file "add-wine-shortcut" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/other/add-wine-shortcut"
chmod +x "add-wine-shortcut"
source add-wine-shortcut
check_and_delete "add-wine-shortcut"
}
function setup_wine() {
banner
print_to_config "installed_wine"
if [[ "$installed_wine" == "stock" ]]; then
print_msg "${BOLD}Installing Wine Natively In Termux"
echo
package_install_and_check "wine-stable"
run_wine_shortcut_script
elif [[ "$installed_wine" == "mobox" ]]; then
print_msg "${BOLD}Addind Mobox Launch Option To Termux"
echo
print_msg "${C}${BOLD}After the installation finishes, make sure to install Mobox using their official instructions"
echo
print_msg "${BOLD}Mobox:- ${C}https://github.com/olegos2/mobox"
echo
sleep 4
download_file "$PREFIX/bin/wine" "https://raw.githubusercontent.com/LinuxDroidMaster/Termux-Desktops/main/scripts/termux_native/mobox_run.sh"
chmod +x "$PREFIX/bin/wine"
cp "$PREFIX/share/applications/wine-explorer.desktop" "$HOME/Desktop/MoboxExplorer.desktop"
run_wine_shortcut_script
elif [[ "$installed_wine" == "wine_hangover" ]]; then
package_install_and_check "hangover-wine"
run_wine_shortcut_script
if [[ ! -f "$PREFIX/bin/wine" ]]; then
ln -s "$PREFIX/bin/hangover-wine" "$PREFIX/bin/wine"
fi
elif [[ "$installed_wine" == "skip" ]]; then
print_msg "${C}Skipping wine Installation..."
else
print_msg "Installing Wine Natively In Termux"
echo
package_install_and_check "wine-stable"
run_wine_shortcut_script
fi
}
#########################################################################
#
# Add Autostart
#
#########################################################################
function add_vnc_autostart() {
print_msg "${BOLD}Adding vnc to autostart"
if grep -q "^vncstart" "$shell_rc_file"; then
print_msg "Termux:X11 start already exist"
else
cat <>"$shell_rc_file"
# Start Vnc
if ! pgrep Xvnc > /dev/null; then
echo "${G}Starting Vnc...${NC}"
vncstart
fi
EOF
fi
}
function add_tx11_autostart() {
print_msg "${BOLD}Adding Termux:x11 to autostart"
if grep -q "^tx11start" "$shell_rc_file"; then
print_msg "Termux:X11 start already exist"
else
cat <>"$shell_rc_file"
# Start Termux:X11
termux_x11_pid=\$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
if [ -z "\$termux_x11_pid" ]; then
echo "${G}Starting Termux:x11...${NC}"
tx11start
fi
EOF
fi
}
function add_to_autostart() {
print_to_config "de_on_startup"
if [[ "$de_on_startup" == "y" ]]; then
if [[ "$default_gui_mode" == "vnc" ]]; then
add_vnc_autostart
elif [[ "$default_gui_mode" == "termux_x11" ]] || [[ "$gui_mode" == "termux_x11" ]]; then
add_tx11_autostart
fi
if [[ "$gui_mode" == "both" ]]; then
print_to_config "default_gui_mode"
fi
fi
}
#########################################################################
#
# Finish | Notes
#
#########################################################################
function cleanup_cache() {
banner
print_msg "Cleaning up the cache..."
if [[ "$PACKAGE_MANAGER" == "pacman" ]]; then
pacman -Scc --noconfirm
else
apt clean all
fi
}
function add_common_function() {
check_and_delete "$PREFIX/etc/termux-desktop/common_functions"
cat <<'EOF' >"$PREFIX/etc/termux-desktop/common_functions"
#!/data/data/com.termux/files/usr/bin/bash
R="$(printf '\033[1;31m')"
G="$(printf '\033[1;32m')"
Y="$(printf '\033[1;33m')"
B="$(printf '\033[1;34m')"
C="$(printf '\033[1;36m')"
NC="$(printf '\033[0m')"
BOLD="$(printf '\033[1m')"
TERMUX_DESKTOP_PATH="/data/data/com.termux/files/usr/etc/termux-desktop"
CONFIG_FILE="$TERMUX_DESKTOP_PATH/configuration.conf"
LOG_FILE="/data/data/com.termux/files/home/termux-desktop.log"
EOF
typeset -f check_termux log_debug print_success print_failed print_warn print_msg wait_for_keypress check_and_create_directory check_and_delete check_and_backup download_file check_and_restore detact_package_manager package_install_and_check package_check_and_remove get_file_name_number extract_zip_with_progress extract_archive download_and_extract count_subfolders confirmation_y_or_n get_latest_release install_font_for_style select_an_option read_conf print_to_config >>"$PREFIX/etc/termux-desktop/common_functions"
chmod +x "$PREFIX/etc/termux-desktop/common_functions"
}
function delete_installer_file() {
current_script_path="$(realpath "$0")"
if [[ "$current_script_path" != */bin* ]]; then
if [[ -f "${current_path}/setup-termux-desktop" ]]; then
(exec rm -- "${current_path}/setup-termux-desktop") &
else
print_failed "Installer file not found"
fi
fi
}
function notes() {
banner
print_msg "Installation Successfull..."
echo
sleep 2
print_msg "${C}${BOLD}Now Restart Termux ${G}(Must)"
echo
print_msg "${C}${BOLD}Some basic commands:-${G}(Must know)"
echo
print_msg "tx11start to start the gui with termux:x11"
echo
print_msg "tx11stop to stop the gui with termux:x11"
echo
print_msg "tx11stop -f to force stop the gui with termux:x11"
echo
if [[ "$gui_mode" == "both" ]]; then
print_msg "vncstart to start the gui with vnc"
echo
print_msg "vncstop to stop the gui with vnc"
echo
fi
if [[ "$distro_add_answer" == "y" ]]; then
print_msg "${C}run:- $selected_distro, to login into $selected_distro"
fi
echo
print_msg "${C}${BOLD}See Uses Section in github to know how to use it"
echo
print_msg "${C}URL:- ${B}https://github.com/sabamdarif/termux-desktop/blob/main/README.md#5-usage-instructions"
echo
if [[ "$distro_add_answer" == "y" ]]; then
print_msg "${C}${BOLD}See how to use Linux distro container"
echo
print_msg "${C}URL:- ${B}https://github.com/sabamdarif/termux-desktop/blob/main/docs/proot-container.md"
fi
}
#########################################################################
#
# Remove
#
#########################################################################
function remove_desktop_environments() {
if [[ "$de_name" == "xfce" ]]; then
package_check_and_remove "xfce4 xfce4-goodies xfce4-pulseaudio-plugin xfce4-battery-plugin xfce4-docklike-plugin xfce4-notifyd-static kvantum gtk2-engines-murrine"
elif [[ "$de_name" == "lxqt" ]]; then
package_check_and_remove "lxqt xorg-xsetroot papirus-icon-theme xwayland kvantum"
elif [[ "$de_name" == "openbox" ]]; then
package_check_and_remove "openbox polybar xorg-xsetroot lxappearance wmctrl feh xwayland kvantum thunar firefox mpd rofi bmon xcompmgr xfce4-settings gedit"
elif [[ "$de_name" == "mate" ]]; then
package_check_and_remove "mate*"
package_check_and_remove "marco mousepad xfce4-taskmanager lximage-qt"
elif [[ "$de_name" == "i3wm" ]]; then
package_check_and_remove "i3"
elif [[ "$de_name" == "dwm" ]]; then
package_check_and_remove "dwm"
elif [[ "$de_name" == "bspwm" ]]; then
package_check_and_remove "bspwm"
elif [[ "$de_name" == "awesome" ]]; then
package_check_and_remove "awesome"
elif [[ "$de_name" == "fluxbox" ]]; then
package_check_and_remove "fluxbox xorg-xsetroot xorg-xprop lxappearance wmctrl feh firefox rofi bmon xcompmgr gtk3 gedit xmllint"
elif [[ "$de_name" == "gnome" ]]; then
package_check_and_remove "gnome*"
package_check_and_remove "thunar xfce4-terminal"
elif [[ "$de_name" == "cinnamon" ]]; then
package_check_and_remove "cinnamon nemo gnome-terminal gnome-screenshot eog"
fi
}
function remove_termux_desktop() {
if [[ ! -e "$CONFIG_FILE" ]]; then
print_msg "${C}${BOLD}Please Install Termux Desktop First"
exit 1
else
banner
print_msg "${R}${BOLD} Remove Termux Desktop"
echo ""
confirmation_y_or_n "Are You Sure You Want To Remove Termux Desktop Completely" ask_remove
if [[ "$ask_remove" == "n" ]]; then
print_msg "${BOLD}Canceling..."
exit 0
else
print_msg "${R}${BOLD}Removeing Termux Desktop"
sleep 3
read_conf
#remove basic packages
package_check_and_remove "pulseaudio x11-repo tur-repo"
#remove desktop related packages
remove_desktop_environments
package_check_and_remove "kvantum xwayland pulseaudio file-roller pavucontrol gnome-font-viewer evince galculator libwayland-protocols xorg-xrdb"
#remove zsh
if [[ "$chosen_shell_name" == "zsh" ]]; then
package_check_and_remove "zsh"
check_and_delete "$HOME/.zsh_history $HOME/.zshrc"
fi
#remove terminal utility
if [[ "$terminal_utility_setup_answer" == "y" ]]; then
check_and_delete "$PREFIX/etc/motd.sh $HOME/.termux $HOME/.fonts/font.ttf $HOME/.termux/colors.properties"
check_and_restore "$PREFIX/etc/motd"
check_and_restore "$PREFIX/etc/motd-playstore"
check_and_restore "$PREFIX/etc/motd.sh"
check_and_restore "$HOME/.termux/colors.properties"
if grep -q "motd.sh$" "$PREFIX/etc/termux-login.sh"; then
sed -i "s|.*motd\.sh$|# |" "$PREFIX/etc/termux-login.sh"
fi
package_check_and_remove "nerdfix fontconfig-utils bat eza"
fi
#remove browser
if [[ "$installed_browser" == "firefox" ]]; then
package_check_and_remove "firefox"
elif [[ "$installed_browser" == "chromium" ]]; then
package_check_and_remove "chromium"
elif [[ "$installed_browser" == "all" ]]; then
package_check_and_remove "firefox chromium"
fi
#remove ide
if [[ "$installed_ide" == "code" ]]; then
package_check_and_remove "code-oss code-is-code-oss"
elif [[ "$installed_ide" == "neovim" ]]; then
package_check_and_remove "neovim lua51 lua-language-server stylua tree-sitter-lua"
elif [[ "$installed_ide" == "geany" ]]; then
package_check_and_remove "geany"
elif [[ "$installed_ide" == "all" ]]; then
package_check_and_remove "code-oss code-is-code-oss geany neovim lua51 lua-language-server stylua tree-sitter-lua"
fi
#remove media player
if [[ "$installed_media_player" == "vlc" ]]; then
package_check_and_remove "vlc-qt-static"
elif [[ "$installed_media_player" == "audacious" ]]; then
package_check_and_remove "audacious"
elif [[ "$installed_media_player" == "both" ]]; then
package_check_and_remove "vlc-qt-static audacious"
fi
#remove photo editor
if [[ "$installed_photo_editor" == "gimp" ]]; then
package_check_and_remove "gimp"
elif [[ "$installed_photo_editor" == "audacious" ]]; then
package_check_and_remove "audacious"
elif [[ "$installed_photo_editor" == "both" ]]; then
package_check_and_remove "gimp audacious"
fi
#remove wine
if [[ "$installed_wine" == "stock" ]]; then
package_check_and_remove "wine"
elif [[ "$installed_wine" == "mobox" ]]; then
print_msg "${C}${BOLD}Make Sure To Uninstall Mobox Using Their Instruction"
check_and_delete "$HOME/Desktop/MoboxExplorer.desktop"
sleep 4
elif [[ "$installed_wine" == "wine_hangover" ]]; then
package_check_and_remove "hangover-wine"
fi
check_and_delete "$PREFIX/bin/wine $PREFIX/share/applications/wine-*"
#remove styles
if [[ "$style_answer" == "5" ]]; then
package_check_and_remove "eww"
fi
#Remove folders and other files
check_and_delete "$PREFIX/share/backgrounds $themes_folder $icons_folder $PREFIX/etc/termux-desktop"
check_and_delete "$HOME/.config/$the_config_dir"
check_and_delete "$HOME/Desktop $HOME/Downloads $HOME/Videos $HOME/Pictures $HOME/Music"
#remove hw packages
package_check_and_remove "mesa-zink virglrenderer-mesa-zink vulkan-loader-android angle-android virglrenderer-android mesa-vulkan-icd-freedreno mesa-vulkan-icd-wrapper mesa-zink"
#remove distro container
if [[ "$distro_add_answer" == "y" ]]; then
proot-distro remove "$selected_distro"
proot-distro clear-cache
package_check_and_remove "proot-distro"
check_and_delete "$PREFIX/bin/$selected_distro $PREFIX/bin/pdrun"
fi
#remove vnc and termux x11
check_and_delete "$PREFIX/bin/gui"
if [[ "$gui_mode" == "termux_x11" ]]; then
package_check_and_remove "termux-x11-nightly xorg-xhost"
check_and_delete "$PREFIX/bin/tx11start $PREFIX/bin/tx11stop"
elif [[ "$gui_mode" == "both" ]]; then
package_check_and_remove "termux-x11-nightly tigervnc xorg-xhost"
check_and_delete "$PREFIX/bin/tx11start $PREFIX/bin/tx11stop $HOME/.vnc/xstartup $PREFIX/bin/vncstart $PREFIX/bin/vncstop $PREFIX/bin/gui $PREFIX/bin/tx11start $PREFIX/bin/tx11stop"
# shellcheck disable=SC2164
cd "$PREFIX/share/zsh/site-functions"
check_and_delete "_add2menu _distro _setup-termux-desktop _tx11start _tx11stop _vncstart _vncstop"
# shellcheck disable=SC2164
cd "$PREFIX/share/bash-completion/completions"
check_and_delete "add2menu distro setup-termux-desktop tx11start tx11stop vncstart vncstop"
# shellcheck disable=SC2164
cd "$HOME"
# remove appstore
package_check_and_remove "aria2 python python3 cloneit"
check_and_delete "${PREFIX}/opt/appstore"
check_and_delete "${PREFIX}/share/applications/org.sabamdarif.termux.appstore.desktop"
fi
check_and_delete "$PREFIX/etc/termux-desktop $PREFIX/bin/setup-termux-desktop"
clear
print_msg "${BOLD}Everything remove successfully"
fi
fi
}
#########################################################################
#
# Change Style
#
#########################################################################
function gui_check_up() {
termux_x11_pid=$(pgrep -f "app_process -Xnoimage-dex2oat / com.termux.x11.Loader :${display_number}")
vnc_server_pid=$(pgrep -f "vncserver")
de_pid=$(pgrep -f "$de_startup")
if [[ -n "$termux_x11_pid" ]] || [[ -n "$de_pid" ]] || [[ -n "$vnc_server_pid" ]] >/dev/null 2>&1; then
echo "${G}Please Stop The Gui Desktop Server First${NC}"
exit 0
fi
}
function change_style() {
if [[ ! -e "$CONFIG_FILE" ]]; then
echo -e "${C} It look like you haven't install the desktop yet\n Please install the desktop first${NC}"
exit 1
else
read_conf
gui_check_up
banner
download_file "${current_path}/styles.md" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/docs/${de_name}_styles.md"
style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
check_and_delete "${current_path}/styles.md"
print_msg "Your currently installed style is ${C}${BOLD}$style_name"
echo
sleep 2
unset style_name
questions_theme_select
rm -rf ~/.cache/sessions/*
setup_config
banner
print_msg "Style changed successfully"
echo
print_msg "Your currently installed style is ${C}${BOLD}$style_name"
fi
}
#########################################################################
#
# Change Hardware Acceleration
#
#########################################################################
function do_hw_changes() {
try_to_autodetect_gpu
setup_device_gpu_model
hw_questions
update_sys
hw_config
if [[ "$gui_mode" == "termux_x11" ]]; then
setup_tx11start_cmd
some_fixes
elif [[ "$gui_mode" == "both" ]]; then
setup_tx11start_cmd
setup_vncstart_cmd
some_fixes
fi
if [[ "$distro_add_answer" == "y" ]]; then
get_distro_container_source
# shellcheck disable=SC1091
source "${current_path}/distro-container-setup"
# set the required variables for pdrun
if [[ "$selected_distro_type" == "chroot" ]]; then
termux_home_link=" "
else
termux_home_link="--termux-home"
fi
final_user_name="$user_name"
distro_app_launch_setup
check_and_delete "${current_path}/distro-container-setup"
fi
}
function change_hw() {
# Check if the configuration file exists
if [[ ! -e "$CONFIG_FILE" ]]; then
print_warn "${C}It looks like you haven't installed the desktop yee. Please install the desktop first"
exit 1
else
read_conf
local old_hw_option
old_hw_option="${termux_hw_answer}"
if [[ "$enable_hw_acc" == "y" ]]; then
banner
print_msg "Your current hardware acceleration api for Termux is: ${C}${BOLD}${termux_hw_answer}"
if [[ "$distro_add_answer" == "y" ]]; then
print_msg "Your current hardware acceleration api for $selected_distro is: ${C}${BOLD}${pd_hw_answer}"
fi
confirmation_y_or_n "Do you want to change hardware acceleration api" confirmation_change_hardware_acceleration
if [[ "$confirmation_change_hardware_acceleration" == "y" ]]; then
do_hw_changes
read_conf
if [[ "$old_hw_option" != "$termux_hw_answer" ]]; then
print_success "${BOLD}Hardware acceleration method successfully changed to ${termux_hw_answer}"
exit 0
elif [[ "$old_hw_option" == "$termux_hw_answer" ]]; then
print_success "${BOLD}Hardware acceleration method is still on ${termux_hw_answer}"
exit 0
else
print_failed "Something went wrong during the hardware acceleration process..."
exit 1
fi
fi
elif [[ "$enable_hw_acc" == "n" ]]; then
print_msg "This option can only be used if have Hardware Acceleration enabled"
confirmation_y_or_n "Do you want to enable Hardware Acceleration" confirmation_want_to_enable_hw
if [[ "$confirmation_want_to_enable_hw" == "y" ]]; then
enable_hw_acc="y"
do_hw_changes
read_conf
if [[ "$enable_hw_acc" == "y" ]]; then
print_success "${BOLD}Successfully enable hardware acceleration"
else
print_failed "Some issue occurred during the hardware acceleration change process..."
fi
elif [[ "$confirmation_want_to_enable_hw" == "n" ]]; then
print_msg "Keeping Hardware Acceleration disabled"
exit 0
fi
fi
fi
}
#########################################################################
#
# Change Distro
#
#########################################################################
function add_distro_again() {
print_msg "${BOLD}Do you want to add a Linux distro container"
echo
print_msg "It will help you to install those app which are not avilable in termux"
echo
print_msg "You can launch those installed apps from termux like other apps"
echo
confirmation_y_or_n "Do you want to continue" distro_add_answer
if [[ "$distro_add_answer" == "y" ]]; then
print_to_config "distro_add_answer"
distro_questions
if [[ "$enable_hw_acc" == "y" ]]; then
distro_hw_questions
# call setup_hw_environment_variables from hw-acceleration setup script
# this is needed for pdrun command
get_hw_acceleration_source
# shellcheck disable=SC1091
source "${current_path}/enable-hw-acceleration"
setup_hw_environment_variables
check_and_delete "${current_path}/enable-hw-acceleration"
fi
distro_container_setup
fi
}
function change_distro() {
if [[ ! -e "$CONFIG_FILE" ]]; then
echo -e "${C} It look like you haven't install the desktop yet\n Please install the desktop first${NC}"
exit 1
else
read_conf
banner
if [[ "$distro_add_answer" == "y" ]]; then
local old_distro
old_distro="${selected_distro}"
if [[ -z "$selected_distro_type" ]]; then
if command -v chroot-distro >/dev/null 2>&1; then
selected_distro_type=chroot
else
selected_distro_type=proot
fi
fi
if [[ "$selected_distro_type" == "chroot" ]]; then
if ! timeout 3s su -c "ls /data/local/chroot-distro/installed-rootfs/$selected_distro" >/dev/null 2>&1; then
print_failed "${selected_distro} isn't installed"
add_distro_again
exit 0
fi
else
if [[ ! -d "$PREFIX/var/lib/proot-distro/installed-rootfs/$selected_distro" ]]; then
print_failed "${selected_distro} isn't installed"
add_distro_again
exit 0
fi
fi
print_msg "Your currently installed distro is: ${C}${BOLD}${selected_distro}"
echo
print_msg "${R}Changing distro will delete all the data from your previous distro"
echo
confirmation_y_or_n "Do you want to continue" distro_change_confirmation
if [[ "$distro_change_confirmation" == "y" ]]; then
choose_distro
print_msg "Removing $selected_distro and it's data"
"${selected_distro_type}"-distro remove "${old_distro}"
check_and_delete "$PREFIX/share/applications/pd_added"
check_and_delete "/data/data/com.termux/files/usr/share/bash-completion/completions/${old_distro}"
check_and_delete "/data/data/com.termux/files/usr/share/zsh/site-functions/_${old_distro}"
check_and_delete "$PREFIX/bin/$selected_distro"
get_hw_acceleration_source
# shellcheck disable=SC1091
source "${current_path}/enable-hw-acceleration"
setup_hw_environment_variables
check_and_delete "${current_path}/enable-hw-acceleration"
if [[ "$pd_audio_config_answer" == "y" ]]; then
rm "$HOME/.${selected_distro}-sound-access"
fi
echo
distro_container_setup
else
print_msg "Canceling distro change process..."
sleep 2
exit 0
fi
else
print_msg "It look like you haven't install any distro yet"
echo
add_distro_again
fi
fi
}
#########################################################################
#
# Change Autostart
#
#########################################################################
function change_autostart() {
read_conf
get_shellrc_path
if [[ "$de_on_startup" == "y" ]]; then
confirmation_y_or_n "You are sure you want to change auto" confirmation_change_auto_start
if [[ "$confirmation_change_auto_start" == "y" ]]; then
if grep -q "^vncstart" "$shell_rc_file"; then
sed -i '/# Start Vnc/,/fi/d' "$shell_rc_file"
print_to_config "de_on_startup" "n"
fi
if grep -q "^tx11start" "$shell_rc_file"; then
sed -i '/# Start Termux:X11/,/fi/d' "$shell_rc_file"
print_to_config "de_on_startup" "n"
fi
print_msg "Auto start disabled"
else
print_msg "Keeping auto start enabled"
fi
elif [[ "$de_on_startup" == "n" ]]; then
confirmation_y_or_n "You haven't have auto start enable, do you want to enable it" confirmation_enable_auto_start
if [[ "$confirmation_enable_auto_start" == "y" ]]; then
if [[ "$gui_mode" == "both" ]]; then
print_msg "You chose both vnc and termux:x11 to access gui mode"
echo
print_msg "Which will be your default"
echo
echo "${Y}1. Termux:x11${NC}"
echo
echo "${Y}2. Vnc${NC}"
echo
select_an_option 2 1 autostart_gui_mode_num
if [[ "$autostart_gui_mode_num" == "1" ]]; then
default_gui_mode="termux_x11"
elif [[ "$autostart_gui_mode_num" == "2" ]]; then
default_gui_mode="vnc"
fi
fi
de_on_startup=y
print_to_config "de_on_startup"
add_to_autostart
else
print_msg "Keeping auto start disabled"
fi
fi
}
#########################################################################
#
# Change Display Port
#
#########################################################################
# change the Display Port/Display Number where it will show the output
function change_display() {
read_conf
gui_check_up
if [[ "$gui_mode" == "termux_x11" ]] || [[ "$gui_mode" == "both" ]]; then
print_msg "${BOLD}Your Current Display Port: ${display_number}"
echo
confirmation_y_or_n "Do you want to change the display port" change_display_port
if [[ "$change_display_port" == "y" ]]; then
while true; do
read -r -p "${R}[${C}-${R}]${Y}${BOLD} Type the Display Port number: ${NC}" display_number
if [[ "$display_number" =~ ^[0-9]+$ ]]; then
break
else
print_warn "${R}Please enter a valid number between 0-9"
fi
done
# shellcheck disable=SC2034
call_from_change_display=true
hw_config
setup_tx11start_cmd
print_to_config "display_number"
sed -i "s|DISPLAY=:[0-9]*|DISPLAY=:$display_number|" "${PREFIX}/bin/$selected_distro"
log_debug "Type the Display Port number: $display_number"
fi
else
print_msg "Changing display port only supported in Termux:x11"
fi
}
#########################################################################
#
# Change Desktop Environment / window manager
#
#########################################################################
function change_de() {
read_conf
gui_check_up
print_msg "Your currently installed environments is: ${C}${BOLD}${de_name}"
echo
print_warn "${R}Changing environment will delete all you previous configuration for that environment"
echo
confirmation_y_or_n "Do you want to continue" de_change_confirmation
if [[ "$de_change_confirmation" == "y" ]]; then
old_de_name="$de_name"
ask_to_chose_de
update_sys
install_required_packages
install_desktop
if [[ "$style_answer" == "0" ]]; then
banner
print_msg "${BOLD}Configuring Stock $de_name Style..."
echo
print_to_config "style_answer"
ext_setup_for_stock
else
setup_config
fi
if [[ "$enable_hw_acc" == "y" ]]; then
hw_config
fi
gui_launcher
print_msg "Removeing old $old_de_name environment"
de_name="$old_de_name"
remove_desktop_environments
unset de_name
read_conf
check_desktop_process
add_to_autostart
echo " "
print_msg "Your current environment is $de_name"
fi
}
#########################################################################
#
# Reinstall themes
#
#########################################################################
function reinstall_themes() {
read_conf
gui_check_up
tmp_themes_folder="$PREFIX/tmp/themes"
check_and_create_directory "$tmp_themes_folder"
print_msg "Reinstalling Themes..."
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/theme.tar.gz" "$tmp_themes_folder"
local theme_names
theme_names=$(ls "$tmp_themes_folder")
local theme_name
for theme_name in $theme_names; do
check_and_delete "$themes_folder/$theme_name"
mv "$tmp_themes_folder/$theme_name" "$themes_folder/"
done
print_msg "${BOLD}Themes reinstall successfully"
}
#########################################################################
#
# Reinstall icons
#
#########################################################################
function reinstall_icons() {
read_conf
gui_check_up
tmp_icons_folder="$PREFIX/tmp/icons"
check_and_create_directory "$tmp_icons_folder"
package_install_and_check "gdk-pixbuf"
print_msg "Reinstalling Icons..."
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/icon.tar.gz" "$tmp_icons_folder"
local icon_themes_names
icon_themes_names=$(ls "$tmp_icons_folder")
local icon_theme
for icon_theme in $icon_themes_names; do
check_and_delete "$icons_folder/$icon_theme"
mv "$tmp_icons_folder/$icon_theme" "$icons_folder/"
print_msg "Creating icon cache..."
gtk-update-icon-cache -f -t "$icons_folder/$icons_theme"
gtk-update-icon-cache -f -t "$PREFIX/share/icons/$icons_theme"
done
print_msg "${BOLD}Icons reinstall successfully"
}
#########################################################################
#
# Reinstall config
#
#########################################################################
function reinstall_config() {
read_conf
gui_check_up
tmp_config_folder="$PREFIX/tmp/config"
check_and_create_directory "$tmp_config_folder"
print_msg "Reinstalling Config..."
download_and_extract "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/setup-files/setup-files/${de_name}/look_${style_answer}/config.tar.gz" "$tmp_config_folder"
local dot_config_file_names
dot_config_file_names=$(ls "$tmp_config_folder")
local dot_config_file
for dot_config_file in $dot_config_file_names; do
check_and_delete "$HOME/.config/$dot_config_file"
mv "$tmp_config_folder/$dot_config_file" "$HOME/.config/"
done
print_msg "${BOLD}Config reinstall successfully"
}
#########################################################################
#
# Some Fixes | Finishing Tasks
#
#########################################################################
function add_auto_completion() {
banner
print_msg "Adding auto completions..."
check_and_create_directory "/data/data/com.termux/files/usr/share/zsh/site-functions"
# shellcheck disable=SC2164
cd /data/data/com.termux/files/usr/share/zsh/site-functions
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_setup-termux-desktop"
if [[ "$gui_mode" == "both" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_vncstart"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_vncstop"
fi
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_tx11start"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_tx11stop"
if [[ "$distro_add_answer" == "y" ]]; then
download_file "_${selected_distro}" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_distro"
sed -i "s/distro/${selected_distro}/g" "_${selected_distro}"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/zsh/_add2menu"
fi
check_and_create_directory "/data/data/com.termux/files/usr/share/bash-completion/completions"
# shellcheck disable=SC2164
cd /data/data/com.termux/files/usr/share/bash-completion/completions
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/setup-termux-desktop"
if [[ "$gui_mode" == "both" ]]; then
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/vncstart"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/vncstop"
fi
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/tx11start"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/tx11stop"
if [[ "$distro_add_answer" == "y" ]]; then
download_file "${selected_distro}" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/distro"
sed -i "s/distro/${selected_distro}/g" "${selected_distro}"
download_file "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/completion/bash/add2menu"
fi
cd "$HOME" || return 1
}
function disable_vblank_mode() {
if [[ "$de_name" == "xfce" ]]; then
sed -i 's|||' "$HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml"
fi
}
function some_fixes() {
# samsung oneui-6 audio fixes
local device_brand_name
device_brand_name=$(getprop ro.product.brand | cut -d ' ' -f 1)
if [[ $device_brand_name == samsung* && $ANDROID_VERSION -ge 14 ]]; then
package_install_and_check "libandroid-stub"
# if [[ -e "/system/lib64/libskcodec.so" ]]; then
# grep -q 'export LD_PRELOAD=/system/lib64/libskcodec.so' "$shell_rc_file" || echo 'export LD_PRELOAD=/system/lib64/libskcodec.so' >>"$shell_rc_file"
# fi
fi
# fix blank export in tx11start
sed -i '/^export\s*$/d' "$PREFIX/bin/tx11start"
# tx11start and vncstart
if [[ "$termux_hw_answer" == "mesa_freedreno" ]] || [[ "$termux_hw_answer" == "mesa_zink_freedreno" ]] || [[ "$termux_hw_answer" == "freedreno_kgsl" ]] || [[ $termux_hw_answer == "zink_with_mesa" ]] || [[ $termux_hw_answer == "zink_with_mesa_zink" ]]; then
sed -i "/if ! \$use_nogpu; then/,/fi/ {/if \$use_debug; then/,/fi/d}" "$PREFIX/bin/tx11start"
sed -i "s/^[[:space:]]*&[[:space:]]*$/ /" "$PREFIX/bin/vncstart"
fi
if [[ "$exp_termux_vulkan_hw_answer" != "skip" ]]; then
disable_vblank_mode
if [[ "$installed_browser" == "chromium" ]] || [[ "$installed_browser" == "all" ]]; then
sed -i 's|Exec=/data/data/com.termux/files/usr/bin/chromium-browser %U|Exec=/data/data/com.termux/files/usr/bin/chromium-browser --enable-features=Vulkan %U|' /data/data/com.termux/files/usr/share/applications/chromium.desktop
fi
if [[ "$installed_ide" == "code" ]] || [[ "$installed_ide" == "all" ]]; then
sed -i 's|/data/data/com.termux/files/usr/bin/code-oss|/data/data/com.termux/files/usr/bin/code-oss --enable-features=Vulkan|g' /data/data/com.termux/files/usr/share/applications/code-oss*
fi
fi
# some fixes for gnome and cinnamon desktop
if [[ "$de_name" == "gnome" ]] || [[ "$de_name" == "cinnamon" ]]; then
sed -i "s|||" "$PREFIX/share/dbus-1/system.d/org.freedesktop.UPower.conf"
if [[ "$de_name" == "gnome" ]]; then
cat <"$PREFIX/share/gnome-session/sessions/minimal.session"
[GNOME Session]
Name=Minimal GNOME
RequiredComponents=org.gnome.Shell;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.Sound;
DefaultProvider-wm=gnome-shell
DesktopName=GNOME
EOF
cat <"$PREFIX/bin/gnome-session-minimal"
rm -rf /data/data/com.termux/files/usr/var/run/dbus/pid
dbus-launch --config-file $PREFIX/share/dbus-1/system.conf
UPOWER_CONF_FILE_NAME=$PREFIX/etc/UPower/UPower.conf $PREFIX/libexec/upowerd -d &
gnome-session --session=minimal \$@
EOF
chmod +x "$PREFIX/bin/gnome-session-minimal"
fi
fi
}
# add the basic details into a config file
function print_basic_details() {
local net_condition
local country
net_condition="$(getprop gsm.network.type)"
country="$(getprop gsm.sim.operator.iso-country)"
if [[ -f "$CONFIG_FILE" ]]; then
check_and_backup "$CONFIG_FILE"
fi
cat <"$CONFIG_FILE"
####################################
########## Termux Desktop ##########
####################################
########################
# -:Device Details:- #
########################
#
# Termux Version: ${TERMUX_VERSION}-${TERMUX_APK_RELEASE}
# Device Model: $MODEL
# Android Version: $ANDROID_VERSION
# Free Space: $FREE_SPACE
# Total Ram: $TOTAL_RAM
# Architecture: $APP_ARCH
# System CPU Architecture: $SUPPORTED_ARCH
# Processor: $PROCESSOR_BRAND_NAME $PROCESSOR_NAME
# GPU: $GPU_NAME
# Network Condition: $net_condition
# Country: $country
#
########################
##### Please don't modify this file otherwise some functions won't work #####
EOF
}
function add_installer() {
if [[ ! -e "$PREFIX/bin/setup-termux-desktop" ]]; then
print_msg "Adding setup-termux-desktop installer to bin"
download_file "$PREFIX/bin/setup-termux-desktop" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/setup-termux-desktop"
chmod +x "$PREFIX/bin/setup-termux-desktop"
fi
}
#########################################################################
#
# Update Task
#
#########################################################################
# check for the changes in the installer file
function check_for_update_and_update_installer() {
if [[ -e "$PREFIX/bin/setup-termux-desktop" ]]; then
banner
print_msg "Checking for update..."
echo
check_and_create_directory "$TERMUX_DESKTOP_PATH"
local current_script_hash
local update_installer
current_script_hash=$(curl -sL https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/setup-termux-desktop | sha256sum | cut -d ' ' -f 1)
local local_script_hash
local_script_hash=$(basename "$(sha256sum "$PREFIX/bin/setup-termux-desktop" | cut -d ' ' -f 1)")
if [[ "$local_script_hash" != "$current_script_hash" ]]; then
confirmation_y_or_n "You are using an old installer. Do you want to update it to the latest version" update_installer
if [[ "$update_installer" == "y" ]]; then
check_and_create_directory "$PREFIX/etc/termux-desktop"
mv "$PREFIX/bin/setup-termux-desktop" "$PREFIX/etc/termux-desktop/"
check_and_backup "$PREFIX/etc/termux-desktop/setup-termux-desktop"
add_installer
add_common_function
unset local_script_hash
local new_local_script_hash
new_local_script_hash=$(basename "$(sha256sum "$PREFIX/bin/setup-termux-desktop" | cut -d ' ' -f 1)")
if [[ "$new_local_script_hash" == "$current_script_hash" ]]; then
print_msg "Installer updated successfully"
check_and_delete "$TERMUX_DESKTOP_PATH/skip_update_checkup"
exit 0
else
print_msg "Failed to update the installer"
exit 0
fi
elif [[ "$update_installer" == "n" ]]; then
print_msg "Keeping the old installer"
check_and_create_directory "$TERMUX_DESKTOP_PATH"
touch "$TERMUX_DESKTOP_PATH/skip_update_checkup"
exit 0
fi
else
print_msg "${BOLD}Great, you are using the latest installer"
fi
fi
}
function check_installer_status() {
if [[ -e "$PREFIX/bin/setup-termux-desktop" ]]; then
if [[ ! -e "$TERMUX_DESKTOP_PATH/skip_update_checkup" ]]; then
check_for_update_and_update_installer
else
print_msg "${BOLD}Update check skipped"
print_msg "${BOLD}Use ${C}--update ${G}to force update check"
fi
fi
}
function check_for_appstore_update() {
print_msg "Checking for appstore updates..."
echo
appstore --update
}
#########################################################################
#
# Reset Changes
#
#########################################################################
function reset_changes() {
if [[ ! -e "$CONFIG_FILE" ]]; then
echo -e "${C} It looks like you haven't installed the desktop yet.\n Please install the desktop first.${NC}"
exit 1
else
read_conf
banner
print_msg "Removing $de_name Config..."
set_config_dir
check_and_delete "${config_dirs[@]}"
get_shellrc_path
if [[ "$terminal_utility_setup_answer" == "y" ]]; then
check_and_delete "$PREFIX/etc/motd.sh $HOME/.termux $HOME/.fonts/font.ttf $HOME/.termux/colors.properties"
termux-reload-settings
check_and_restore "$PREFIX/etc/motd"
termux-reload-settings
check_and_restore "$PREFIX/etc/motd-playstore"
check_and_restore "$PREFIX/etc/motd.sh"
termux-reload-settings
check_and_restore "$HOME/.termux/colors.properties"
# shellcheck disable=SC2164
cd /data/data/com.termux/files/usr/share/zsh/site-functions
check_and_delete "_add2menu _distro _setup-termux-desktop _tx11start _tx11stop _vncstart _vncstop"
# shellcheck disable=SC2164
cd /data/data/com.termux/files/usr/share/bash-completion/completions
check_and_delete "add2menu distro setup-termux-desktop tx11start tx11stop vncstart vncstop"
# shellcheck disable=SC2164
cd "$HOME"
if grep -q "motd.sh$" "$PREFIX/etc/termux-login.sh"; then
sed -i "s|.*motd\.sh$|# |" "$PREFIX/etc/termux-login.sh"
termux-reload-settings
fi
rm "$PREFIX/share/applications/wine-*.desktop" >/dev/null 2>&1
check_and_delete "$TERMUX_DESKTOP_PATH"
check_and_delete "$PREFIX/bin/tx11start $PREFIX/bin/tx11stop $PREFIX/bin/vncstop $PREFIX/bin/vncstart $PREFIX/bin/gui $PREFIX/bin/pdrun"
fi
check_and_delete "$HOME/Music"
check_and_delete "$HOME/Downloads"
check_and_delete "$HOME/Desktop"
check_and_delete "$HOME/Pictures"
check_and_delete "$HOME/Videos"
if [[ "$shell_name" == "zsh" ]]; then
chsh -s bash
check_and_delete "$HOME/.oh-my-zsh"
fi
check_and_delete "$shell_rc_file"
check_and_restore "$shell_rc_file"
print_success "${BOLD}Reset successful. Now restart Termux."
fi
}
#########################################################################
#
# Call Functions
#
#########################################################################
check_termux
detact_package_manager
if [[ -z "$1" ]] || [[ "$1" == "--install" ]] || [[ "$1" == "-i" ]]; then
check_installer_status "$1"
fi
current_path=$(pwd)
get_termux_arch
function install_termux_desktop() {
banner
update_sys
cleanup_cache
termux-wake-lock
install_required_packages
recheck_basic_packages
if [[ "$1" != "--local-config" && "$1" != "--config" && "$1" != "-config" ]]; then
print_recomended_msg
fi
if [[ "$1" != "--local-config" && "$1" != "--config" && "$1" != "-config" ]]; then
questions_install_type
if [[ "$install_type_answer" == "1" ]]; then
if [[ "$distro_add_answer" == "y" ]]; then
distro_questions
fi
if [[ "$enable_hw_acc" == "y" ]]; then
setup_device_gpu_model
hw_questions
fi
fi
fi
if [[ "$1" == "--local-config" ]] || [[ "$1" == "--config" ]] || [[ "$1" == "-config" ]]; then
download_file "${current_path}/styles.md" "https://raw.githubusercontent.com/sabamdarif/termux-desktop/refs/heads/main/docs/${de_name}_styles.md"
style_name=$(grep -oP "^## $style_answer\..+?(?=(\n## \d+\.|\Z))" "${current_path}/styles.md" | sed -e "s/^## $style_answer\. //" -e "s/:$//" -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
check_and_delete "${current_path}/styles.md"
fi
print_conf_info
check_and_create_directory "${TERMUX_DESKTOP_PATH}"
log_debug "$CONFIG_FILE"
print_basic_details
setup_necessary_permissions
setup_shell
setup_fonts
install_desktop
browser_installer
ide_installer
media_player_installer
photo_editor_installer
setup_wine
if [[ "$style_answer" == "0" ]]; then
banner
print_msg "${BOLD}Configuring Stock $de_name Style..."
echo
print_to_config "style_answer"
ext_setup_for_stock
else
setup_config
fi
ext_wall_setup
banner
add_common_function
distro_container_setup
gui_launcher
terminal_utility_setup
if [[ "$selected_distro_type" == "proot" ]]; then
install_termux_desktop_appstore
fi
add_to_autostart
check_desktop_process
install_fm_tools
add_auto_completion
some_fixes
cleanup_cache
termux-wake-unlock
add_installer
notes
log_debug "$(cat $CONFIG_FILE)"
delete_installer_file
}
function show_help() {
echo -e "
--debug to create a log file
-i,--install to start installation
-r,--remove to remove termux desktop
-c,--change to change some previous configuration
-ri,--reinstall to reinstall some previously install stuff
--reset to reset all changes made by this script without uninstalling any package
--local-config,-config to start the installation from pre made config file
-h,--help to show help
"
}
function show_change_help() {
echo "options you can use with --change"
echo -e "
style to change installed style
pd,distro to change installed linux distro container
hw,hwa to change hardware acceleration method
autostart to change autostart behaviour
display to change termux:x11 display port
de,wm to switch between diffreent desktop environment or window manager
h,help to show help
example uses : --change style
"
}
function show_reinstall_help() {
echo -e "
options you can use with --reinstall
icons to reinstall icons pack
themes to reinstall themes pack
config to reinstall config
h,help to show help
example uses : --reinstall icons
example uses : --reinstall icons,themes...etc to reinstall them at once
"
}
if [[ $1 == "--debug" ]]; then
trap debug_msg debug
shift
fi
case $1 in
--remove | -r | --uninstall)
remove_termux_desktop
;;
--install | -i | in)
install_termux_desktop "$1"
;;
--change | -c)
case $2 in
style)
# shellcheck disable=SC2034
CALL_FROM_CHANGE_STYLE=true
change_style
;;
distro | pd)
# shellcheck disable=SC2034
CALL_FROM_CHANGE_DISTRO=true
change_distro
;;
hw | hwa)
change_hw
;;
autostart)
change_autostart
;;
display)
change_display
;;
de | wm | desktop | winm | wim)
change_de
;;
h | help | -h | --help)
show_change_help
;;
*)
print_failed "${BOLD} Invalid option: ${C}$2"
print_msg "Use --change help to show help"
;;
esac
;;
--reinstall | -ri)
IFS=',' read -ra OPTIONS <<<"$2"
for option in "${OPTIONS[@]}"; do
case $option in
icons)
reinstall_icons
;;
themes)
reinstall_themes
;;
config)
reinstall_config
;;
h | help | -h | --help)
show_reinstall_help
exit
;;
*)
print_failed "${BOLD} Invalid option: ${C}$option"
print_msg "Use --reinstall help to show help"
;;
esac
done
;;
--update)
check_for_update_and_update_installer "$1"
check_for_appstore_update
;;
--help | -h)
show_help
;;
--reset)
reset_changes
;;
--local-config | --config | -config)
print_recomended_msg
load_local_config "$2"
install_termux_desktop "$1"
;;
*)
if [[ -n "$1" ]]; then
print_failed "${BOLD} Invalid option: ${C}$1"
show_help
else
install_termux_desktop "$1"
fi
if [[ -z "$PREFIX" && "$PREFIX" != *"/com.termux/"* ]]; then
print_failed "${BOLD}Please run it inside termux${NC}"
exit 0
fi
;;
esac