In the past, I've tried using Unity Tweak Tool to change my mouse pointer theme. However, I want to change it from my terminal as well. How can I do this on Ubuntu 16.04?
2 Answers
How settings work under the hood
Each user's profile is managed by DConf
database. You can read more about it my answer on this question: Do GUI based application execute shell commands in the background? Each particular setting has schema - sort of like a URL - and key - a name of a particular setting - associated with it.
Let's find out what setting does Unity Tweak Tool alter when we change cursor theme, by running dconf watch /
and then changing pointer theme in UTT:
$ dconf watch /
/org/gnome/desktop/interface/cursor-theme
'crystalblue_classic'
Great, now we know what schema and key to change !
The gsettings tool - tweaker's friend
Luckily for us there exists a command-line utility called gsettings
, which we can use to alter the settings that we need. This tool is often used in shell scripts. For other types of languages such as Python or C, there exist GSettings libraries which allow us to do the same things. Here we specifically want to use gsettings
because it can be used on command-line.
The difference to note is that unlike dconf
, the schemas are dot-separated, rather than slash-separated. Thus, gsettings
would understand org.gnome.desktop.interface
schema.
Thus, what we can do is this:
$ gsettings set org.gnome.desktop.interface cursor-theme 'redglass'
Notice that in this example I'm using Redglass
as one of the themes that I have installed, which you might not have, so use some of the values that you have listed in UTT.
Finding values of the schema
Typically what can be done to find all possible options on gsettings
schema is to use range
option:
$ gsettings range com.canonical.Unity.Launcher launcher-position
enum
'Left'
'Bottom'
Unfortunately, the schema that we need to use to alter cursor theme doesn't have enum
values:
$ gsettings range org.gnome.desktop.interface cursor-theme
type s
Thus, alternatively, what you can do ( and what UTT apparently does) is to list all directories in /usr/share/icons
folder that have cursors
folder like so:
$ ls -d /usr/share/icons/*/cursors
/usr/share/icons/crystalblue_classic/cursors/ /usr/share/icons/crystalgray_nonanim/cursors/ /usr/share/icons/crystalwhiteleft_nonanim/cursors/
... more output here
And then just select each theme's folder name as new value.
Taking it further - making a shell script
Of course we don't want to deal with several commands over and over. Rather, lets make it simple via a shell script, in this particular case - a bash
script (because we want to make use of advanced features such as arrays and because we're not striving for portability to systems other than Ubuntu) which will list available themes and allow us to select the one we want.
#!/usr/bin/env bash
fifo="/tmp/themes_script.fifo"
mkfifo "$fifo"
declare -a themes
find /usr/share/icons -maxdepth 2 -type d -name "cursors" -printf "%P\n" > "$fifo" &
while IFS= read -r line
do
themes+=("${line%/*}")
done < "$fifo"
rm "$fifo"
echo ">>> Please enter the number of new theme for cursor"
select opt in "${themes[@]}"
do
if [ $REPLY -le ${#themes} ]
then
gsettings set org.gnome.desktop.interface cursor-theme \'$opt\' &&
exit 0
else
echo "Improper argument" > /dev/stderr
exit 1
fi
done
Test run:
bash-4.3$ ./change_cursor_theme.sh
>>> Please enter the number of new theme for cursor
1) crystalblueleft_nonanim 14) crystalgray_nonanim
2) crystalgreenleft_classic 15) DMZ-Black
3) crystalwhite_nonanim 16) crystalgrayleft
4) handhelds 17) crystalblueleft_classic
5) crystalgreen 18) Deepin-sapphire
6) whiteglass 19) crystalwhiteleft
7) crystalgray 20) crystalgreenleft_nonanim
8) crystalwhiteleft_nonanim 21) crystalgrayleft_nonanim
9) redglass 22) DMZ-White
10) crystalblue 23) crystalblueleft
11) crystalwhite 24) crystalblue_nonanim
12) crystalblue_classic 25) crystalgreenleft
13) crystalgreen_nonanim 26) crystalgreen_classic
#? 9
bash-4.3$
-
There is the error in the script. The
${#themes}
should be${#themes[@]}
. Otherwise it's the length of first element of array.– GrAndFeb 27, 2021 at 14:27
on top of Sergiy Kolodyazhnyy's answer above, it is worth checking also the user's local directory, because most themes install there by default:
#!/usr/bin/env bash
fifo="/tmp/themes_script.fifo"
mkfifo "$fifo"
declare -a themes
find /usr/share/icons -maxdepth 2 -type d -name "cursors" -printf "%P\n" > "$fifo" &
find ~/.icons -maxdepth 2 -type d -name "cursors" -printf "%P\n" >> "$fifo" &
while IFS= read -r line
do
themes+=("${line%/*}")
done < "$fifo"
rm "$fifo"
echo ">>> Please enter the number of new theme for cursor"
select opt in "${themes[@]}"
do
if [ $REPLY -le ${#themes} ]
then
gsettings set org.gnome.desktop.interface cursor-theme \'$opt\' &&
exit 0
else
echo "Improper argument" > /dev/stderr
exit 1
fi
done