2

I am trying to get Ubuntu 20.04 LTS ("Focal Fossa") to automatically switch to the "light" Window Theme at 0600 (6AM) every morning, and the "dark" Window Theme at 1800 (6PM) every night.

The following Terminal command can be used to change to the "light" Window Theme:

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

The following Terminal command can be used to change to the "dark" Window Theme:

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

But as noted above, I would like to automate this process.

The first suggestion presented to me was via a cron job, however this has repeatedly proved unsuccessful, so another user suggested a more "modern" approach, via Systemd "timers"... Unfortunately, I am unfamiliar with Systemd and the process of creating timers, so I have be learning as I go, without success to date.

At this time, I have six files in my "home" folder:

  • dark.service
  • dark.timer
  • dark.sh
  • light.service
  • light.timer
  • light.sh

The contents of "dark.service" is:

[Unit]
Description=Automatically change the "Window Theme" to "dark" in the evening.

[Service]
ExecStart=/home/gregory/dark.sh

[Install]
WantedBy=dark.sh

The contents of dark.timer is:

[Unit]
Description=Automatically change the "Window Theme" to "dark" in the evening.

[Timer]
OnCalendar=*-*-* 18:00:00
Persistent=true

[Install]
WantedBy=dark.service

The contents of "dark.sh" is:

export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
gsettings set org.gnome.desktop.interface gtk-theme Yaru-dark

The contents of "light.service" is:

[Unit]
Description=Automatically change the "Window Theme" to "light" in the morning.

[Service]
ExecStart=/home/gregory/light.sh

[Install]
WantedBy=light.sh

The contents of "light.timer" is:

[Unit]
Description=Automatically change the "Window Theme" to "light" in the morning.

[Timer]
OnCalendar=*-*-* 06:00:00
Persistent=true

[Install]
WantedBy=light.service

The contents of "light.sh" is:

export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
gsettings set org.gnome.desktop.interface gtk-theme Yaru-light

I used "Startup Application Preferences" (gnome-session-properties) to run "light.timer" and "dark.timer" on login.

Based on the advice I have been given elsewhere and what I have read online, I think creating "timers" via Systemd is probably the right approach to achieve what I want (automatic switching between "light" and "dark" Window Themes, based on the time of the day)... I just need a little help getting things working, as Systemd, timers and scripts are a whole new world to me.

Gregory Opera
  • 2,639
  • 7
  • 33
  • 59

1 Answers1

2

(Late edit of WantedBy=default.service to WantedBy=default.target)

This may be a long journey, but here are some pointers. All of the WantedBy entries are wrong. They cannot depend on a shell script. A timer unit x.timer is always associated with a service unit x.service. If you were to start the timers, they will start their service at the given time. But you would need to do this at each login. So instead you need to enable the timers, and have systemd start them automatically. To do this you need to have the timers WantedBy= a target that is fulfilled at login for users. Typically, this is default.target. Though there are many system targets, there are very few user targets.

Since your scripts are very short, you might like to include them in the service units, to keep things smaller. The service and timer files have to be in ~/config/systemd/user/. You need to create this directory if it does not exist. Eg: dark.service:

[Unit]
Description=Automatically change the "Window Theme" to "dark" in the evening.
[Service]
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
ExecStart=/usr/bin/gsettings set org.gnome.desktop.interface gtk-theme Yaru-dark

dark.timer:

[Unit]
Description=Automatically change the "Window Theme" to "dark" in the evening.
[Timer]
OnCalendar=*-*-* 18:00:00
Persistent=true
[Install]
WantedBy=default.target

light.service:

[Unit]
Description=Automatically change the "Window Theme" to "light" in the morning.
[Service]
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
ExecStart=/usr/bin/gsettings set org.gnome.desktop.interface gtk-theme Yaru-light

light.timer:

[Unit]
Description=Automatically change the "Window Theme" to "light" in the morning.
[Timer]
OnCalendar=*-*-* 06:00:00
Persistent=true
[Install]
WantedBy=default.target

Whenever you change the content of these files, or add or remove files from this directory, you need to notify systemd by giving the command:

systemctl --user daemon-reload

I'm not sure what gnome "Startup Application Preferences" does. The systemd method to start using these units is to do, once only, not as root:

systemctl --user enable dark.timer light.timer

Now, whenever you login, these units will be started, and stopped when you logout.


While developing the units you may want to test them immediately, without needing to login/logout. You can start them explicitly with:

systemctl --user start dark.timer light.timer

and you can stop them with

systemctl --user stop dark.timer light.timer

You need to stop them before you can start them again. You can combine stop and start with

systemctl --user restart dark.timer light.timer

You can check their status with

systemctl --user list-timers

which should say when they will next trigger, and what service they will run.

It would be nice to have a tutorial on systemd user units, but I haven't found anything suitable. They mostly talk about system units. You can glean some basics from this large redhat document, but it is for administrators, so a little too detailed, but it would help to understand that some of it is in common for user units.

meuh
  • 3,211
  • So do I even need the (separate) script files ("dark.sh" and "light.sh")? – Gregory Opera May 12 '20 at 22:43
  • Also, where should the "service" and "timer" files be located (they're currently in my "home" directory)?

    When I try to enable them, it tells me that "they don't exist"!

    – Gregory Opera May 12 '20 at 22:52
  • The service and timer files have to be in ~/config/systemd/user/. You need to create this directory if it does not exist. You don't need the separate .sh files in this example. – meuh May 13 '20 at 05:39
  • I moved the service / timer files to ~/.config/systemd/user/ (i.e. the hidden directory), but it tells me: `NEXT LEFT LAST PASSED UNIT ACTIVATES

    0 timers listed. Pass --all to see loaded but inactive timers, too.`

    The same is true when I apply the --all flag.

    – Gregory Opera May 13 '20 at 06:34
  • I've updated my answer with more info. You might be able to see just the modifications here. You should try to read some background material on using systemd units, including man systemctl. – meuh May 13 '20 at 07:18
  • @GregoryOpera when you create or modify a unit file, you have to reload systemd to make it aware of the changes (systemctl daemon-reload). For user sessions, systemctl --user daemon-reload – muru May 13 '20 at 07:18
  • Well I couldn't get the test (systemctl --user start dark.timer or systemctl --user start light.timer) to work (it didn't seem to change the theme one way or another), but when I run systemctl --user list-timers, it says they're running and scheduled appropriately... So I will manually change to the "dark" theme and see if it changes back in the morning. I'll probably reboot my system before I go to bed too, just to be sure... – Gregory Opera May 13 '20 at 11:43
  • Hmm... After a reboot, it was not showing any timers (inactive or inactive) until I ran systemctl --user restart dark.timer light.timer. I'll see if it changes back to the "light" theme in the morning, if it does, I just need to find a way to automate systemctl --user restart dark.timer light.timer so that I don't need to do it every time I reboot my computer... – Gregory Opera May 13 '20 at 12:54
  • Did you do the enable step? This is getting a bit big; perhaps you could accept this answer and start a new post with any further problems so others have a chance to contribute. – meuh May 13 '20 at 13:08
  • 1
    It worked (switched from the "dark" theme to the "light" theme this morning) - but it is definitely NOT starting automatically after a reboot... If I run systemctl --user list-timers it shows no timers; if I run systemctl --user restart dark.timer light.timer and THEN run systemctl --user list-timers, the timers show up and seem to work.

    I will open a new question for this.

    – Gregory Opera May 13 '20 at 23:12