Files
eos-bash-shared/eos-script-lib-yad

1055 lines
37 KiB
Bash

#!/bin/bash
#
# EndeavourOS bash scripts "library". Functions using 'yad'.
#
# - ALL FUNCTIONS HERE START WITH "eos_yad_" AND ARE EXPORTED.
# - NO GLOBAL VARIABLES ARE USED NOR PROVIDED.
#
# User MUST declare the following exports in the *using* bash code:
#
# export -f eos_yad
# export -f eos_yad_terminal
# export -f eos_yad_check_internet_connection
# export -f eos_yad_GetArgVal
# export -f eos_yad_RunCmdTermBash
# export -f eos_yad_problem
# export -f eos_yad_DIE
# export -f eos_yad_WARN
#
# export -f eos_yad__detectDE
# export -f eos_yad_GetDesktopName
# export -f eos_GetArch
# export -f eos_select_browser
# export -f eos_yad_nothing_todo
#
# The two last functions above do not use yad.
#
# shellcheck disable=SC1090 # Don't show warnings on sourceing via a variable
source /etc/eos-color.conf
source /etc/eos-script-lib-yad.conf # for EOS_ROOTER and other configs
export EOS_WICON=/usr/share/endeavouros/EndeavourOS-icon.png
export EOS_YAD_STARTER_CMD="/usr/bin/yad --window-icon=$EOS_WICON"
# Avoid hyphens in function names because of POSIX standard, use underscores instead.
eos_yad() { GDK_BACKEND=x11 $EOS_YAD_STARTER_CMD "$@"; }
translations_dir=/usr/share/endeavouros/scripts # needed in translations.bash
source $translations_dir/translations.bash || {
echo "$translations_dir/translations.bash not found!" >&2
exit 1
}
CanRunYad() {
[ -x /bin/yad ] || return 1 # fail, yad not installed
[ -d /usr/include/webkitgtk-4.1 ] || return 2 # fail, webkit2gtk-4.1 not installed
return 0 # OK
}
yad_missing_check() {
if [ "${EOS_YAD_MISSING_NOTIFICATION^^}" = "YES" ] ; then
if ! which yad &>/dev/null ; then
local app="$1"
local timeout="$2"
[ "$timeout" ] || timeout=10000
local msg="Some operations require yad installed."
eos_notification "$ICO_INFO" normal $timeout "$app" "Notification from $app" "$msg"
fi
fi
}
eos_assert_deps() { # params: prog deps
local -r prog="$1"
shift
local failcount=0
local dep
for dep in "$@" ; do
pacman -Q "$dep" &>/dev/null || {
echo "==> $prog requires package '$dep'" >&2
((failcount++))
}
done
return $failcount
}
eos_icon_path() {
# on success, echo full icon path and return 0
# on failure, return 1
local -r type="$1"
local -r name="$2"
local icon family
case "$type" in
actions|animations|apps|categories|devices|emblems|emotes|filesystems|intl|mimetypes|places|status|stock) ;;
*) return 1 ;;
esac
case "$name" in
"") return 1 ;;
esac
# use Qogir as default, then try other icons
for family in Qogir "${EOS_ICON_SETS_PREFERENCE[@]}" # may check Qogir twice...
do
family=${family##*/}
# echo "$FUNCNAME: family = $family" >&2
icon="/usr/share/icons/$family/scalable/$type/$name.svg" # find only scalable icons
if [ -e "$icon" ] ; then
echo "$icon"
return 0
fi
done
return 1
}
AssignIconVariables_in_eos_bash_shared() {
export ICO_INFO_WEB=$(eos_icon_path apps internet-web-browser)
if false && [ -x /bin/xdg-mime ] ; then
local default_app="$(xdg-mime query default text/html)" # 'xdg-mime query default' may issue a warning on KDE if run with elevated privileges
case "$default_app" in
chromium.desktop)
export ICO_INFO_WEB=$(eos_icon_path apps chromium) ;;
firefox.desktop)
export ICO_INFO_WEB=$(eos_icon_path apps firefox) ;;
firefoxdeveloperedition.desktop)
export ICO_INFO_WEB=$(eos_icon_path apps firefox-developer-edition) ;;
opera.desktop)
export ICO_INFO_WEB=$(eos_icon_path apps opera) ;;
vivaldi-stable.desktop)
export ICO_INFO_WEB=$(eos_icon_path apps vivaldi) ;;
*)
export ICO_INFO_WEB=$(eos_icon_path apps browser) ;;
esac
fi
case "$CurrentDesktop" in
kde) export ICO_CALAMARES=/usr/share/icons/breeze-dark/apps/48/calamares.svg ;;
*) export ICO_CALAMARES=$(eos_icon_path apps calamares) ;;
esac
export ICO_NEWS=$(eos_icon_path apps newsflash)
export ICO_CHANGES=$(eos_icon_path mimetypes text-x-changelog)
export ICO_HELP=$(eos_icon_path apps system-help)
export ICO_LOG=$(eos_icon_path apps utilities-log-viewer)
export ICO_INSTALL=$(eos_icon_path apps system-software-install)
export ICO_UPDATE=$(eos_icon_path apps system-software-update)
export ICO_SYSTOOLS=$(eos_icon_path apps applications-utilities)
export ICO_QUESTION=$(eos_icon_path apps system-help)
export ICO_TIPS=$(eos_icon_path apps user-info)
export ICO_INFO=$(eos_icon_path apps dialog-information)
export ICO_ERROR=$(eos_icon_path apps system-error)
export ICO_PREFERENCES_SYSTEM=$(eos_icon_path apps preferences-system)
export ICO_NOTIFICATION=$(eos_icon_path apps preferences-system-notifications)
export ICO_NOTIFICATION_DISABLE=$(eos_icon_path apps preferences-desktop-notifications)
export ICO_SHARE=$(eos_icon_path apps share)
export ICO_SAVE=$(eos_icon_path actions document-save)
export ICO_MIRROR_RANK=$(eos_icon_path apps preferences-system-performance)
export ICO_EDIT_CONFIG=$(eos_icon_path apps dconf-editor)
export ICO_SCHEDULE=$(eos_icon_path apps preferences-system-time)
export ICO_RESET=$(eos_icon_path apps system-restart)
export ICO_OPERATION_TEST=$(eos_icon_path apps system-run)
export ICO_CONNECTION=$(eos_icon_path apps org.gnome.Connections)
export ICO_BLUETOOTH=$(eos_icon_path devices bluetooth)
export ICO_DISK=$(eos_icon_path devices drive-harddisk)
export ICO_NO_CONNECTION=/usr/share/icons/Qogir/24/panel/nm-no-connection.svg
export ICO_WARNING=/usr/share/icons/Qogir/scalable/apps/gnome-warning.svg
# export ICO_WARNING=/usr/share/icons/Qogir/32/status/dialog-warning.svg
}
# Icons for various use cases like
# --field=...
# --image=...
# --button=...
if false ; then
export WELCOME_ICON_SYSTEM_LOGS=search # face-worried
export WELCOME_ICON_LEAVE=stop # face-crying
export WELCOME_ICON_HONEST=face-angel
export WELCOME_ICON_INSTALL_TAB=system-software-install # $(eos_IconGrasp system-software-install)
export WELCOME_ICON_PARTITION_MANAGER=gparted # $(eos_IconGrasp gparted)
export WELCOME_ICON_BLUETOOTH=bluetooth # $(eos_IconGrasp bluetooth)
export WELCOME_ICON_TOGGLE_r8169_DRIVER=system-software-update # $(eos_IconGrasp system-software-update)
export WELCOME_ICON_CHANGE_RESOLUTION=preferences-desktop-display
export WELCOME_ICON_CHANGE_DISPLAY_MANAGER=preferences-desktop-display
export WELCOME_ICON_INSTALL_OFFICIAL=calamares
export WELCOME_ICON_INSTALL_COMMUNITY=calamares
export WELCOME_ICON_INSTALL_INFO=$WELCOME_ICON_INSTALL_TAB
export WELCOME_ICON_MIRROR_UPDATE=software-update-available # or applications-internet ?
export WELCOME_ICON_BLUETOOTH_INFO=$WELCOME_ICON_BLUETOOTH
export WELCOME_ICON_LATEST_RELEASE=user-info # or info ?
export WELCOME_ICON_INSTALLATION_TIPS=user-info
export WELCOME_ICON_SYSTEM_RESCUE=user-info
export WELCOME_ICON_SYSTEM_LOGS_HOWTO=user-info
export WELCOME_ICON_WEBSITE=user-info # or info ?
export WELCOME_ICON_WIKI=user-info
export WELCOME_ICON_NEWS=user-info
export WELCOME_ICON_FORUM=user-info
export WELCOME_ICON_DONATE=user-info
export WELCOME_ICON_ABOUT_WELCOME=user-info
export WELCOME_ICON_SYSTEM_UPDATE=system-software-update
export WELCOME_ICON_PACCACHE_SRV=applications-system
export WELCOME_ICON_UPDATE_NOTIFIER_CONF=preferences-system
export WELCOME_ICON_WALLPAPER_SET_DEFAULT=preferences-desktop-wallpaper
export WELCOME_ICON_WALLPAPER_SET=preferences-desktop-wallpaper
export WELCOME_ICON_WALLPAPER_DOWNLOAD=preferences-desktop-wallpaper
export WELCOME_ICON_XFCE_THEME_VANILLA=preferences-desktop-theme
export WELCOME_ICON_XFCE_THEME_EOS=preferences-desktop-theme
export WELCOME_ICON_INITIAL_TAB=preferences-system
export WELCOME_ICON_EOS_GENERIC=endeavouros-icon
export WELCOME_ICON_TIPS=user-info
export WELCOME_ICON_ARM=system-run
export WELCOME_ICON_RUNINTERMINAL=preferences-system
export WELCOME_ICON_QUESTION=dialog-question
export WELCOME_ICON_INFO=dialog-information
export WELCOME_ICON_PREFERENCES=preferences-system # was: system-preferences
export WELCOME_ICON_OWN_COMMANDS=applications-other
export WELCOME_ICON_HELP=help-about
export WELCOME_ICON_ERROR=dialog-error
export WELCOME_ICON_WARNING=dialog-warning
export WELCOME_ICON_APPDEV=applications-development
export WELCOME_ICON_CHANGELOG=applications-development
export WELCOME_ICON_HELP_CONTENTS=help-contents
export WELCOME_ICON_NOTIFICATIONS=notifications
export WELCOME_ICON_NOTIFICATIONS_DISABLED=notifications-disabled
fi
eos_GetArch() {
local arch; arch="$(/usr/bin/uname -m)"
case "$arch" in
armv7* | aarch64) arch=armv7h ;;
esac
printf "%s" "$arch"
}
EosSudoEditor() {
local editor ed1
for editor in "${EOS_SUDO_EDITORS[@]}" rnano nano vim "emacs -nw" "$SUDO_EDITOR" "$VISUAL" "$EDITOR" ; do
ed1="${editor%% *}"
if /usr/bin/which "$ed1" >& /dev/null ; then
case "$ed1" in
mousepad | /bin/mousepad | /usr/bin/mousepad) editor="/usr/bin/dbus-launch $editor" ;;
esac
echo "$editor"
return 0
fi
done
return 1
# DIE "suitable editor not found"
}
eos_GetProgName() { echo "${0##*/}" ; }
eos_select_browser() {
# Select an existing browser.
# User may export a variable _WELCOME_BROWSER to use the preferred browser.
# Additionally, variable _WELCOME_BROWSER_OPTIONS may include browser options.
if [ -n "$_WELCOME_BROWSER" ] ; then
if [ -n "$_WELCOME_BROWSER_OPTIONS" ] ; then
echo "$_WELCOME_BROWSER $_WELCOME_BROWSER_OPTIONS"
else
echo "$_WELCOME_BROWSER"
fi
return
fi
# If _WELCOME_BROWSER is not exported, use the user configurable list of browsers
# in file /etc/eos-script-lib-yad.conf
local old_list="xdg-open exo-open kde-open firefox chromium vivaldi-stable opera" # for backwards compatibility
local browser
for browser in "${EOS_PREFERRED_BROWSERS[@]}" $old_list
do
if (/usr/bin/which "$browser" >& /dev/null) ; then
echo "$browser"
return
fi
done
eos_yad_WARN "${FUNCNAME[0]}: cannot find a browser"
}
eos_workaround_fix_critical_urgency() {
# libnotify 0.8.4-1 workaround:
# For notification's critical urgency,
# value 0 for --expire-time does not work, any other value works (?)
# or don't use --expire-time at all.
[ "$urgency" = critical ] || cmd+=(--expire-time="'$expiretime'")
}
eos_notification() { # sending notification to the current user
local icon="$1"
local urgency="$2" # low, normal, critical
local expiretime="$3"
local appname="$4"
local summary="$5"
local body="$6"
local action="$7"
[ "$urgency" ] || urgency=normal
local cmd=(
notify-send
--icon="$icon"
--urgency="$urgency"
--app-name="$appname"
"$summary"
"$body"
)
eos_workaround_fix_critical_urgency
if [ -n "$action" ] ; then
cmd+=(--action="$action")
fi
"${cmd[@]}"
}
eos_GetUsers() {
local file=""
for file in /var/run/{u,w}tmp ; do
[ -e $file ] && break || file=""
done
printf "%s\n" $(/usr/bin/users $file) | sort -u
}
eos_notification_all_debug() {
[ $_notification_debug = yes ] && echo -e "==> ${FUNCNAME[1]}: debug:" "$@" >> "$_debugout"
}
eos_notification_all() { # sending notification to all users
local icon="$1"
local urgency="$2" # low, normal, critical
local expiretime="$3" # milliseconds
local appname="$4"
local summary="$5" # title
local body="$6" # msg
local color="$7" # message color (for TTY): RED, YELLOW, or "" (empty or no value means plain text)
local username="$8" # optional, user who gets the notifications
local -r _notification_debug=yes # set to 'no' later
local -r _debugout="/tmp/${FUNCNAME[0]}-debug.log"
[ -e "$_debugout" ] && rm -f "$_debugout"
[ -n "$urgency" ] || urgency=normal
# [ "$body_to_tty" = "yes" ] && echo "==> INFO: $body" >&2 # meant to print to TTY
if [ "$XDG_SESSION_TYPE" = "tty" ] || [ -z "$DISPLAY$WAYLAND_DISPLAY" ] || [ "$TERM" = "linux" ] || [[ $(tty) =~ /dev/tty ]] ; then
if [ $_notification_debug = yes ] ; then
[ "$XDG_SESSION_TYPE" = "tty" ] && eos_notification_all_debug "XDG_SESSION_TYPE = tty"
[ -z "$DISPLAY" ] && eos_notification_all_debug "DISPLAY = ''"
[ -z "$WAYLAND_DISPLAY" ] && eos_notification_all_debug "WAYLAND_DISPLAY = ''"
[ "$TERM" = "linux" ] && eos_notification_all_debug "TERM = linux"
[[ $(tty) =~ /dev/tty ]] && eos_notification_all_debug "/usr/bin/tty matched /dev/tty"
fi
local -r C_RESET="$RESET"
local C_ON=""
# bold colors
case "$color" in
YELLOW) C_ON="$YELLOW" ;;
RED) C_ON="$RED" ;;
esac
printf "%s==> %s%s\n" "$C_ON" "$body" "$C_RESET" >&2
return
fi
local users user userid
local cmd=()
local display="" wayland_display=""
eos_notification_all_debug "username = '$username'"
if [ "$username" ] ; then
users="$username"
else
users="$(eos_GetUsers)"
fi
eos_notification_all_debug "users = '$users'"
[ "$DISPLAY" ] && display="DISPLAY=$DISPLAY"
for user in $users ; do
userid="$(/usr/bin/id -u "$user")"
wayland_display=$(GetWaylandDisplay "$userid")
eos_notification_all_debug "user = '$user'; display = '$display'; wayland_display = '$wayland_display'"
cmd=(
$display # Note: format is VARIABLE=value (or empty)
$wayland_display # Note: format is VARIABLE=value (or empty)
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$userid/bus"
notify-send
--icon="'$icon'"
--urgency="'$urgency'"
--app-name="'$appname'"
"'$summary'"
"'$body'"
)
eos_workaround_fix_critical_urgency
# /usr/bin/su "$user" -c "${cmd[*]}"
/usr/bin/sudo -u "$user" bash -c "${cmd[*]}"
done
}
GetWaylandDisplay() { # returns either "WAYLAND_DISPLAY=value" or ""
local userid="$1"
local wd="$(/bin/ls -1 /run/user/$userid/wayland-*.lock 2>/dev/null | sed -E "s|/run/user/$userid/(wayland-[^\.]+).lock|\1|")"
[ "$wd" ] && wd="WAYLAND_DISPLAY=$wd"
echo "$wd"
}
eos_yad_terminal() {
local conf=/etc/eos-script-lib-yad.conf
if [ -r $conf ] ; then
source $conf
if [ -n "$EOS_YAD_TERMINAL" ] ; then
if [ -x /usr/bin/"${EOS_YAD_TERMINAL%% *}" ] || [ -x "${EOS_YAD_TERMINAL%% *}" ] ; then # allow options in $EOS_YAD_TERMINAL"
echo "$EOS_YAD_TERMINAL"
return
fi
echo "Sorry, terminal program '$EOS_YAD_TERMINAL' is not available. Please check your configuration file $conf." | \
eos_yad --text-info --title=Warning --height=100 --width=500 --wrap --button=yad-ok:0
fi
fi
# Show a terminal that is capable of supporting option -e properly. Empty if not found.
# Requires: yad
#
# These terminal programs are known not to work with this program:
# - putty
# The following terminals are known to work:
local suitable_terminals=(
xfce4-terminal
konsole
gnome-terminal
mate-terminal
lxterminal
deepin-terminal
terminator
qterminal
alacritty
tilix
termite
xterm
kitty
terminology
sakura
ghostty
foot # wayland
wezterm
)
local xx
for xx in "${suitable_terminals[@]}" ; do
if [ -x "/usr/bin/${xx%% *}" ] ; then # allow options for the "suitable terminals"
echo "/usr/bin/$xx"
return 0
fi
done
printf "%s\n %s\n%s" \
"Sorry, none of the terminal programs:" \
"${suitable_terminals[*]}" \
"is installed. Some features may not work as expected." \
| eos_yad --text-info \
--title="Warning" --height=200 --width=700 --wrap --button=yad-ok:0
return 1
}
eos_yad_check_internet_connection() {
local verbose="$1" # yes|verbose = show dialog, otherwise don't show dialog
local waitrounds="$2" # try max $waitrounds times for a connection, test once per $onewait
local onewait="$3" # time to wait in one waiting round
local caller="$4" # who is calling this function (often empty)
local ix
local title="Warning"
local checker="ping -c 1 8.8.8.8"
case "$EOS_CONNECTION_CHECKER" in
curl)
# checker="curl --silent --connect-timeout 8 https://8.8.8.8"
checker=eos-connection-checker
;;
esac
test -z "$verbose" && verbose=no
test -z "$waitrounds" && waitrounds=5
test -z "$onewait" && onewait=1s
if [ -n "$caller" ] ; then
title+=" from $caller"
fi
for ((ix=0; ix<waitrounds; ix++)) ; do
$checker >/dev/null && return 0 # is connected
sleep $onewait
done
$checker >/dev/null || {
case "$verbose" in
[yY]*|1|true|TRUE|True|on|enable*|verbose)
if [ 0 -eq 1 ] ; then
echo "No internet connection!" | \
eos_yad --text-info --title="$title" \
--height=100 --width=300 --justify=center --wrap \
--button=yad-quit:1 \
--button=" Continue anyway!go-next!Don't stop me now":0
else
eos_notification "$ICO_WARNING" normal 60000 "$caller" "$title" "No internet connection!"
fi
;;
*)
return 1
;;
esac
}
}
eos_yad_GetArgVal() { echo "${1#*=}" ; }
eos_yad_RunCmdTermBashOpt() { # like eos_yad_RunCmdTermBash, but supports certain options
local cmd=""
local prompt=""
local termopts=""
local waitopt=""
local opts
local retval
# Handle options for variables cmd ... waitopt.
opts="$(getopt -o=p:t:w:E --longoptions prompt:,term:,wait:,no-enter-wait --name "${FUNCNAME[0]}" -- "$@")"
retval=$?
[ $retval -eq 0 ] || return 1
eval set -- "$opts"
while true ; do
case "$1" in
--prompt | -p)
prompt="$2" ; shift ;;
--term | -t)
termopts="$2" ; shift ;; # e.g. --term="-T 'my title' --geometry=100x200"
--wait | -w)
waitopt="$2" ; shift ;; # either --wait="--no-enter-wait" or --wait="sleep=30" (30 (seconds) can be something else too)
--no-enter-wait | -E)
waitopt="--no-enter-wait" ;; # alternative to --wait
--)
shift; break ;;
esac
shift
done
cmd="$*"
[ -n "$cmd" ] || { echo "${FUNCNAME[0]}: warning: required command is missing." >&2; return 1; }
# Get the available/configured terminal.
local term; term="$(eos_yad_terminal)"
test -n "$term" || return 1
mkdir -p "$HOME/.cache"
local tmpfile; tmpfile=$(mktemp "$HOME/.cache/${FUNCNAME[0]}.XXXXX")
trap "sleep 0.2; rm -f '$tmpfile'" EXIT
echo "#!/bin/bash" >> "$tmpfile"
test -n "$prompt" && echo "echo $prompt" >> "$tmpfile"
echo "$cmd" >> "$tmpfile"
echo "echo" >> "$tmpfile"
case "$term" in
/usr/bin/deepin-terminal | deepin-terminal) ;;
*)
_init_translations
case "$waitopt" in
--no-enter-wait | no-enter-wait) ;;
sleep=*)
local waittime="${waitopt#*=}"
echo "eos-sleep-counter $waittime" >> "$tmpfile"
;;
*)
echo "read -p '$(ltr updt_press_enter): '" >> "$tmpfile"
;;
esac
;;
esac
echo "sleep 0.5" >> "$tmpfile"
echo "rm -f $tmpfile" >> "$tmpfile" # this may cause issues in very special cases!
chmod +x "$tmpfile"
# Try make sure terminal $term does not return to the caller immediately
# but waits until the commands from $tmpfile are executed.
case "$term" in
/usr/bin/gnome-terminal | gnome-terminal)
$term $termopts --wait -- "$tmpfile" 2>/dev/null ;;
/usr/bin/xfce4-terminal | xfce4-terminal)
$term --disable-server $termopts -e "$tmpfile" 2>/dev/null ;;
*)
$term $termopts -e "$tmpfile" 2>/dev/null ;;
esac
# The following DOES NOT WORK with plain gnome-terminal:
#echo "Deleting '$tmpfile'."
#rm -f "$tmpfile"
}
eos_yad_RunCmdTermBash() {
local cmd="$1"
local prompt="$2"
local termopts="$3"
local waitopt="$4"
eos_yad_RunCmdTermBashOpt --prompt="$prompt" --term="$termopts" --wait="$waitopt" "$cmd"
}
eos_yad_problem() {
local title="$1"
shift
eos_yad --text-info --title="$title" --wrap --image=$ICO_ERROR \
--width=700 --height=500 --button=yad-quit:0 "$@"
# removed --tail
}
eos_yad_DIE() {
# This function is only for small messages.
# The local Usage can be used only if it is
# - defined before sourcing this file
# - exported
local msg="$1"
local title="Error"
shift
while true ; do
echo "$msg"
# run Usage function if available (usually is not ...)
test -n "$(declare -F | grep -w '^declare -f Usage$')" && Usage
break
done | eos_yad_problem "$title" "$@"
exit 1
}
eos_yad_WARN() {
local msg="$1"
local title="Warning"
shift
echo "$msg" | eos_yad_problem "$title" --image=$ICO_WARNING "$@"
}
# Function detectDE is copied from: https://cgit.freedesktop.org/xdg/xdg-utils/tree/scripts/xdg-utils-common.in
#--------------------------------------
# Checks for known desktop environments.
# Returning the value, two alternative ways:
# a. Set variable named DE to the name of the desktop environment, in lowercase.
# b. User given variable (as the first parameter) gets the value.
# With this mode user can give option --toupper (as a second parameter) to convert the value to uppercase.
# (Also option --tolower is supported.)
eos_yad__detectDE()
{
local variable_from_arg=no # use variable DE by default
local toupper=no # do not convert to uppercase by default
case "$1" in
"")
local _desktop_="" # will assign variable named DE if the desktop is found
;;
*) # will assign the user given variable name in "$1" with the DE value, if found
local -n _desktop_="$1" # _desktop_ refers to the user given variable
variable_from_arg=yes
case "$2" in
--toupper) toupper=yes ;;
--tolower) toupper=no ;; # tolower is already the default...
esac
;;
esac
# see https://bugs.freedesktop.org/show_bug.cgi?id=34164
unset GREP_OPTIONS
case "${XDG_CURRENT_DESKTOP}" in
# only recently added to menu-spec, pre-spec X- still in use
Budgie*) _desktop_=budgie ;;
Cinnamon|X-Cinnamon) _desktop_=cinnamon ;;
DEEPIN|[Dd]eepin) _desktop_=deepin ;;
ENLIGHTENMENT|Enlightenment) _desktop_=enlightenment ;;
GNOME*|gnome) _desktop_=gnome ;; # GNOME, GNOME-Classic:GNOME, or GNOME-Flashback:GNOME
KDE) _desktop_=kde ;;
LXDE) _desktop_=lxde ;;
LXQt) _desktop_=lxqt ;;
MATE) _desktop_=mate ;;
XFCE) _desktop_=xfce ;;
X-Generic) _desktop_=generic ;; # ???
i3) _desktop_=i3 ;;
esac
if [ -z "$_desktop_" ]; then # fallback to checking $DESKTOP_SESSION
case "$DESKTOP_SESSION" in
gnome) _desktop_=gnome ;;
LXDE|Lubuntu) _desktop_=lxde ;;
MATE) _desktop_=mate ;;
plasma) _desktop_=kde ;;
xfce|xfce4|'Xfce Session') _desktop_=xfce ;;
openbox) _desktop_=openbox ;;
esac
fi
if [ "$_desktop_" = "" ]; then
# classic fallbacks
if [ x"$KDE_FULL_SESSION" != x"" ]; then _desktop_=kde;
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then _desktop_=gnome;
elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then _desktop_=mate;
elif dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager &>/dev/null ; then _desktop_=gnome;
elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then _desktop_=xfce;
elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then _desktop_=xfce
elif echo "$DESKTOP" | grep -q '^Enlightenment'; then _desktop_=enlightenment;
elif [ x"$LXQT_SESSION_CONFIG" != x"" ]; then _desktop_=lxqt;
elif [ -x /usr/bin/qtile ] && [ -d /usr/share/doc/qtile ] ; then
_desktop_="qtile"
elif eos_IsSway ; then
_desktop_=sway
elif eos_IsBspwm ; then
_desktop_=bspwm
fi
fi
if [ "$_desktop_" = "" ]; then
# fallback to uname output for other platforms
case "$(uname 2>/dev/null)" in
CYGWIN*) _desktop_=cygwin ;;
Darwin) _desktop_=darwin ;;
esac
fi
# if [ "$_desktop_" = "gnome" ]; then
# gnome-default-applications-properties is only available in GNOME 2.x
# but not in GNOME 3.x
# which gnome-default-applications-properties > /dev/null 2>&1 || _desktop_="gnome3" # This is no more needed (?)
# fi
if [ -z "$_desktop_" ]; then # ??
if [ -f "$XDG_RUNTIME_DIR/flatpak-info" ]; then
_desktop_="flatpak"
fi
fi
if [ -z "$_desktop_" ] ; then
if [ -x /usr/bin/inxi ] ; then
_desktop_=$(echo $(inxi -Sc0) | sed -E 's|.* Desktop\: ([^ ]*) .*|\1|')
_desktop_=${_desktop_,,} # make all lowercase
fi
fi
[ $toupper = yes ] && _desktop_=${_desktop_^^}
case "$variable_from_arg" in
no) [ -n "$_desktop_" ] && DE="$_desktop_" ;;
esac
}
GetCurrentDesktop() { # Gives current desktop name in lowercase.
local -n _de="$1" # Variable from caller, "returns" the desktop name to the caller.
eos_yad__detectDE _de --tolower
}
# These 2 easy funcs display the DE/WM in upper case letters:
eos_yad_GetDesktopName() {
local _de=""
eos_yad__detectDE _de --toupper
echo "$_de"
}
eos_GetDeOrWm() { eos_yad_GetDesktopName ; }
eos_IsSway() {
case "$DESKTOP_SESSION" in
sway | */sway) return 0 ;;
esac
case "$XDG_SESSION_DESKTOP" in
sway | */sway) return 0 ;;
esac
[ -x /usr/bin/swaybg ] && return 0
return 1
}
eos_IsBspwm() {
case "$DESKTOP_SESSION" in
bspwm | */bspwm) return 0 ;;
esac
case "$XDG_SESSION_DESKTOP" in
bspwm | */bspwm) return 0 ;;
esac
[ -x /usr/bin/bspwm ] && return 0
return 1
}
# DIE() { eos_yad_DIE "$@" ; } # deprecated
# WARN() { eos_yad_WARN "$@" ; } # deprecated
#SetBrowser() {
# local xx
# for xx in xdg-open exo-open firefox chromium ; do # use one of these browser commands
# if [ -x /usr/bin/$xx ] ; then
# _BROWSER=/usr/bin/$xx # for showing external links
# return
# fi
# done
# DIE "${FUNCNAME[0]}: cannot find a browser"
#}
eos_yad_nothing_todo() {
local text="$1"
local timeout="$2" # optional, default set below
local title="$3" # optional, default set below
local image="$4" # optional, default set below
[ -n "$timeout" ] || timeout=10
[ -n "$title" ] || title="Info"
[ -n "$image" ] || image=$ICO_INFO
local cmd=(
eos_yad --form --text="$text" --title="$title" --no-focus --image="$image"
--height=100 --width=300 --timeout="$timeout" --timeout-indicator=left
--button=yad-close:0
)
"${cmd[@]}"
}
FindAvailableMonoFont() {
local size="$1"
local font="Mono" # fallback
[ -n "$size" ] || size=10
if [ -r /usr/share/fonts/liberation/LiberationMono-Regular.ttf ] ; then
font="Liberation Mono"
elif [ -r /usr/share/fonts/TTF/DejaVuSansMono.ttf ] ; then
font"DejaVu Sans Mono"
elif [ -r /usr/share/fonts/noto/NotoSansMono-Regular.ttf ] ; then
font="Noto Sans Mono"
elif [ -r /usr/share/fonts/gsfonts/NimbusMonoPS-Regular.otf ] ; then
font="Nimbus Mono"
elif [ -r /usr/share/fonts/adobe-source-code-pro/SourceCodePro-Regular.otf ] ; then
font="Source Code Pro"
fi
echo "$font $size"
}
ProgressBar() { # This function was converted from the work of @Kresimir, thanks!
local msg="$1"
local percent="$2"
local barlen="$3"
local c
local columns="$COLUMNS" # nr of columns on the terminal
[ -n "$columns" ] || columns=80 # guess nr of columns on the terminal
local msglen=$((columns - barlen - 9)) # max space for the msg
[ "${#msg}" -gt "$msglen" ] && msg="${msg::$msglen}" # msg must be truncated
[ "${msg: -1}" = ":" ] || msg+=":" # make sure a colon is after msg
printf "\r%-*s %3d%% [" "$msglen" "$msg" "$percent" >&2
for ((c = 0; c < barlen; c++)) ; do
if (( c <= percent * barlen / 100 )); then
echo -ne "#" >&2
else
echo -ne " " >&2
fi
done;
stdbuf -oL printf "]" >&2 # flush stdout
}
ProgressBarInit() {
# progress bar initialization
trap 'printf "\x1B[?25h" >&2' EXIT # cursor on
printf "\x1B[?25l" >&2 # cursor off
}
ProgressBarEnd() {
printf "\n" >&2
}
YadProgressPulsate() {
local lockfile="$1"
local text="$2"
while true ; do
[ -r "$lockfile" ] || return
echo 0
sleep 0.1s
done | eos_yad --progress \
--title="Progress indicator" \
--text="$text" \
--auto-close \
--width=400 --hide-text --pulsate
}
eos_FormMonoText() {
local txt="$1"
local size="$2" # optional
[ -n "$size" ] && size=" $size"
printf "<span font='Mono$size'>%s</span>" "$txt"
}
Wget2Curl() {
# Convert a wget call to a curl call.
local opts
# shellcheck disable=SC2154 # don't complain about undefined $progname
local _progname="$progname" # $progname may come from the user app
[ -n "$_progname" ] || _progname="$(eos_GetProgName)"
opts="$(/usr/bin/getopt -o=qO: --longoptions timeout:,user-agent: --name "$_progname" -- "$@")" || {
PreLog "${FUNCNAME[0]}: option handling failed!"
return 1
}
eval set -- "$opts"
local cmd=(curl --fail --location)
local retval=0
while true ; do
case "$1" in
-q) cmd+=(--silent) ;;
-O) cmd+=(--output "$2"); shift ;;
--user-agent) cmd+=(--user-agent "$2"); shift ;;
--timeout) cmd+=(--max-time "$2"); shift ;;
--) shift ; break ;;
esac
shift
done
# [ "$foobar_test" = "yes" ] && echo "${cmd[*]} $*"
"${cmd[@]}" "$@"
retval=$?
#if [ "$foobar_test" = "yes" ] ; then
# case "$retval" in
# 23) echo "==> Write error. Curl could not write data to a local filesystem or similar." ;;
# 0) ;;
# *) echo "==> curl returned $retval." ;;
# esac
#fi
return $retval
}
eos_is_installing() {
if [ "$LOGNAME" = "liveuser" ] || [ "$USER" = "liveuser" ] ; then
if [ -x /usr/bin/calamares ] ; then
return 0 # installing
fi
fi
return 1 # not installing
}
# check the config:
if eos_is_installing ; then
export EOS_ROOTER="sudo bash -c"
else
case "$EOS_ROOTER" in
su | "su -c" | "/usr/bin/su -c" | "") export EOS_ROOTER="eos-run-cmd-with-su" ;; # default!
sudo | "sudo bash -c" | "/usr/bin/sudo bash -c") export EOS_ROOTER="sudo bash -c" ;;
doas | "doas bash -c" | "/usr/bin/doas bash -c") export EOS_ROOTER="doas bash -c" ;; # experimental!
pkexec | "pkexec bash -c" | "/usr/bin/pkexec bash -c") export EOS_ROOTER="/usr/bin/pkexec bash -c" ;;
su-c_wrapper) export EOS_ROOTER="/usr/bin/su-c_wrapper bash -c" ;;
*)
eos_yad_DIE "Error: configuration '$EOS_ROOTER' for EOS_ROOTER in file /etc/eos-script-lib-yad.conf is not supported!"
;;
esac
fi
eos_running_kernel() {
# Output the name of the running kernel, e.g. 'linux-lts'.
# If unable to determine the running kernel, output nothing.
# Note the alternative (fallback) implementations below.
local running_kernel=""
local pkgbase="/usr/lib/modules/$(uname --kernel-release)/pkgbase"
if [ -r "$pkgbase" ] ; then
# running_kernel="$(cat "$pkgbase")"
running_kernel="$(< "$pkgbase")"
case "$running_kernel" in
linux*) echo "$running_kernel" ; return ;;
esac
fi
if [ -r /proc/version ] ; then
# running_kernel="$(cat /proc/version | sed 's|.*(\([^@]*\)@archlinux).*|\1|')"
running_kernel=$(</proc/version) # example line: ...(linux@archlinux)...
running_kernel=${running_kernel%%@*} # drop all after "@", including
running_kernel=${running_kernel##*\(} # drop all before "(", including
case "$running_kernel" in
linux*) echo "$running_kernel" ; return ;;
esac
fi
if [ -r /proc/cmdline ] ; then
# running_kernel=$(cat /proc/cmdline | awk '{print $1}' | sed 's|^.*/vmlinuz-\(.*\)$|\1|') # works only with grub
running_kernel=$(</proc/cmdline) # example line: BOOT_IMAGE=/boot/vmlinuz-linux root=UUID=...
running_kernel=${running_kernel##*/vmlinuz-} # drop all before "linux"
running_kernel=${running_kernel%% *} # drop all after " "
case "$running_kernel" in
linux*) echo "$running_kernel" ; return ;;
esac
fi
}
eos_is_in_chroot() {
if [ "$EUID" != "0" ] ; then
echo "==> $FUNCNAME(): elevated privileges required." >&2
echo " -> $FUNCNAME() called from file ${BASH_SOURCE[1]}, line ${BASH_LINENO[0]}." >&2
return 0
fi
[ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]
}
_bg_or_bashdb() {
# If the "main" function of a script should run in background *and*
# sometimes the script needs to be debugged with bashdb,
# the script can use this function to start running.
# Assumption: the script has a single "main" function that starts the execution.
# For example:
# _bg_or_bashdb <main-function-of-a-script> "$@"
# See also: the 'akm' app.
case "$_Dbg_debugger_name" in
bashdb) "$@" ;; # when debugging with bashdb, do not run in background
*) "$@" & ;; # otherwise run in background
esac
}
GetPager() { # return a pager out of some known pagers
local app
local pager_apps=("less -RF" bat most more cat)
[ "$PAGER" ] && pager_apps=("$PAGER" "${pager_apps[@]}")
for app in "${pager_apps[@]}" ; do
if [ -x /bin/${app%% *} ] ; then
echo "/bin/$app"
return
fi
done
}
GetCacheDir() {
local pconfcachedir=$(grep "^[ ]*CacheDir[ ]*=" /etc/pacman.conf | tail -n1)
if [ "$pconfcachedir" ] ; then
pconfcachedir=$(echo "$pconfcachedir" | sed -E 's|^[ ]*CacheDir[ ]*=[ ]*(.*)|\1|')
echo "$pconfcachedir"
else
echo /var/cache/pacman/pkg/
fi
}