5

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 2

4

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$ 
1
  • There is the error in the script. The ${#themes} should be ${#themes[@]}. Otherwise it's the length of first element of array.
    – GrAnd
    Feb 27, 2021 at 14:27
0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .