Last active
September 19, 2021 14:24
-
-
Save rifazn/584a94d6f79e13b320180e7c9ec81eea to your computer and use it in GitHub Desktop.
A shell script to toggle between light and dark variants of a GTK theme.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# A small POSIX compliant script to toggle between dark and light variant | |
# of a theme for GNOME based desktops. | |
# Copyright (C) 2021 Rifaz Nahiyan | |
# This code is licensed under the MIT License. | |
# View the license in its entirety at: https://opensource.org/licenses/MIT | |
get_current_theme () { | |
gsettings get org.gnome.desktop.interface gtk-theme | tr --delete \' | |
} | |
set_theme () { | |
gsettings set org.gnome.desktop.interface gtk-theme "$1" | |
# Unfortunately, gsettings always reports exit status 0 | |
} | |
## Sanity checks | |
deps_check () { | |
deps="gsettings notify-send" | |
missing="" | |
for dep in ${deps}; do | |
command -v "${dep}" >/dev/null || missing="${missing} ${dep}" | |
done | |
if [ -n "${missing}" ] | |
then | |
die "Missing necessary dependencies: ${missing}" | |
fi | |
unset missing | |
} | |
# Display a formatted message, then exit with error | |
die () { | |
printf "%s: %s\n" "${0##*/}" "${*}" >&2 | |
exit 1 | |
} | |
# Get the script's basename and trim the '.sh' (if any) at the end | |
SCRIPTNAME="${0##*/}" | |
SCRIPTNAME="${SCRIPTNAME%.sh}" | |
main () { | |
# Check if necessary and optional dependecies are there, else exit | |
deps_check | |
current_theme="$(get_current_theme)" | |
# Check if the theme name has "dark" or "Dark" at the end of its name, | |
# then set new theme accordingly | |
case $current_theme in | |
*-[dD]ark) | |
new_theme="${current_theme%-[Dd]ark}" | |
;; | |
*) | |
# Extra check for Arc theme as it breaks convention by using captial 'D' | |
if [ "$current_theme" = "Arc" ]; then | |
new_theme="$current_theme"-Dark | |
else | |
new_theme="$current_theme"-dark | |
fi | |
DARK="dark" | |
;; | |
esac | |
set_theme "$new_theme" | |
notify_msg="Theme switched to ${DARK:-light} variant." | |
notify-send -t 5000 "${SCRIPTNAME}" "$notify_msg" | |
} | |
main "${@}" |
Right. Exiting with 1
almost objectively makes more sense and we are also printing to stderr for removing ambiguity. Also, command -v $program
itself exits with 1
and not 127
or something, so we can piggy-back off that.
About checking whether a theme exists, gsettings
does not provide any API for that, so the best thing currently to do is to check whether a directory with the theme name exists in: /usr/share/themes/
and ~/.themes/
.
Updated code with the dependency checks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unfortunately, there's no universal way to verify if a command is usable without actually trying to invoke it (for example,
docker
may be installed, but if you're not in thedocker
group, then commands likedocker info
will return a nonzero status other than127
), so it really comes down to how much you want your script to be able to handle and which tools you're anticipating to work with.Simply checking for their existence, seems to be well defined via POSIX with
command -v ${utility}
found a reference.Your modification to
die()
makes sense, with the caveat that you probably don't (usually) want your script exiting with status 127, as something else could be watching for that then erroneously report to it's caller that your script doesn't exist. Also, you'd want to be sure it actually gets passed a value that can be accessed as$2
, so something like${2:-255}
, or whatever the default exit code should be, would prevent it from potentially resolving toexit 0
.This is one problem that some people undoubtedly have some pretty strong opinions on, but the best solution is the one that works best for your needs.