Automatic Light / Dark Mode?

For GNOME, this shell extension exists: Night Theme Switcher

It has quite a lot of options and already works out of the box, without having to configure anything, but the configuration is straight forward as well!

Screenshot of the Schedule tab

Screenshot of the GTK theme tab


The terminal command for changing theme is:

gsettings set org.gnome.desktop.interface gtk-theme Yaru-dark

for the Yaru-dark theme, and

gsettings set org.gnome.desktop.interface gtk-theme Yaru-light

for the Yaru-light theme.

Now, there's something called cron-job for scheduling jobs (basically executing something, repeatedly at specific time). So, you can write a cron-job to execute these commands at specified times (something like change to dark theme at 9 PM and light theme at 6 AM).

Add the following to a file named script.sh:

#!/bin/bash
echo export DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS > lightscript.sh
echo export DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS > darkscript.sh
echo "gsettings set org.gnome.desktop.interface gtk-theme Yaru-light" >> lightscript.sh
echo "gsettings set org.gnome.desktop.interface gtk-theme Yaru-dark" >> darkscript.sh
chmod 755 lightscript.sh
chmod 755 darkscript.sh

currenttime=$(date +%H:%M)
if [[ "$currenttime" > "21:00" ]] || [[ "$currenttime" < "06:00" ]]; then
  ./darkscript.sh
else
  ./lightscript.sh
fi

Make the file executable running:

chmod 755 /path/to/script.sh

or:

chmod +x /path/to/script.sh

Run gnome-session-properties in terminal. Add a new start up program by clicking add on right side and selecting the script.sh file by browsing and save it with some name and comment. This will tell GNOME to create lightscript.sh and darkscript.sh whenever you login through GUI.

Add your job (change theme) to crontab by using the command:

crontab -e

and choosing a suitable editor or you can go to /var/spool/cron/crontabs and edit the file with your username. Accessing the file this way requires sudo privileges. Add the following two lines (with /path/to/ replaced by actual path):

0 6 * * * /path/to/lightscript.sh
0 21 * * * /path/to/darkscript.sh

It will say:

crontab: installing new crontab

after exiting the command. You can also check with:

crontab -l

This should do it. The above two lines tell cron to execute lightscript.sh at 6:00 AM and darkscript.sh at 9:00 PM everyday.

We are taking this detour instead of just adding:

0 6 * * * gsettings set org.gnome.desktop.interface gtk-theme Yaru-light

to crontab because this requires the DBUS_SESSION_BUS_ADDRESS variable to be set correctly.