I’ve probably mentioned my “overnight script,” before. I’ve never published it, because it ties tightly to my workflow, installed software, and file storage, and so can’t really imagine it helping anybody. Structurally, it runs while I sleep (or try to sleep, depending on the night), giving me a text-to-speech time on a keystroke or a place to type notes if something comes to mind during the night. When I terminate the process in the morning, it sets up most of what I need for the day, including a few scheduled tasks.

Sundown

Meanwhile, I’ve finally realized that I don’t want my computer to have a light mode or a dark mode. I want both, depending on the time. During daylight hours, dark mode has sub-standard contrast, at least to my eyes and screen. At night, I find light color schemes too harsh.

Gee, Settings…

Pleasantly, we can change most of what I need at the command line, and therefore in a script. For the GNOME Desktop, the gsettings utility handles this. An example follows.

gsettings set org.gnome.desktop.interface color-scheme prefer-light

By itself, this only switches the system setting to light mode.

Many aspects of the system and many applications have settings, which we can find with the same utility.

gsettings list-recursively

Poking around, we can find two additional settings of relevance.

gsettings set org.gnome.settings-daemon.plugins.color night-light-enabled false
gsettings set org.gnome.gedit.preferences.editor scheme 'solarized-light'

This turns off (and back on) GNOME’s Night Light, which reddens the “color temperature” of the screen, and sets the default editor’s color scheme. Between these two configuration options and the one above, at least in theory, I can set up a fairly complete “day mode” and “night mode.” I leave that as a theory, because at this time, my version of Ubuntu doesn’t always propagate the desktop color scheme setting to all applications until I open the settings application. Even so, that comes fairly close.

Side Effects

I should note that many websites take advantage of the @media (prefers-color-scheme: dark) CSS query, to show a light/dark mode, depending on the preference set in the web browser. And most browsers have a setting that says to prefer whatever the operating system uses.

Therefore, by setting the browser to follow the operating system, changing GNOME’s color-scheme affects many websites on load, which enhances this process nicely.

Showdown at Sundown

However, this doesn’t fit the mission statement. Having the ability to kick off day or night helps, but automating this would work better, and fit my scripting idea. I could do this with a cron job, if I wanted this to happen at the same time every day, but I don’t. I want the screen to go dark around when the sun goes down. (I wouldn’t do this on an on-site office computer, by the way. The color temperature change helps readiness in falling asleep, and that doesn’t work so well on the job, especially for people who need to commute home.)

Scheduling something at sundown requires knowing what time to expect sundown. After some poking around, I found sunwait, which can calculate sunrise or sunset, with an option for various angles, if you want a time slightly before or after, or have a specific kind of sun-up/down in mind, plus modifiers for people who don’t live at sea level. After setting latitude and longitude variables, that gives me something like this.

sunset=$(sunwait list 1 set "$latitude" "$longitude")
echo "gsettings set org.gnome.gedit.preferences.editor scheme 'solarized-dark'" | at "$sunset"
echo "sleep 45; gsettings set org.gnome.desktop.interface color-scheme prefer-dark" | at "$sunset"
echo "gsettings set org.gnome.settings-daemon.plugins.color night-light-enabled true" | at "$sunset"

I believe that I needed to install at. It schedules the command provided as input text at the time provided as a parameter, like cron, but it only works once per call. I’d prefer it if it had the ability to take the command as a parameter, too, instead of that oddball piping arrangement, but we don’t always get what we want…

And yes, with three commands to call, and a couple more coming below, it would make more sense to put them all in a script, and have a command-line argument govern whether to change to light or dark mode. Then call that with the at utility. I’ll leave that as an exercise for the reader.

Otherwise, this gets the time of day for today’s sunset, then schedules the three “dark mode” tasks for that time. Note that for one of them, the system color scheme preference, I stagger that by almost a minute, because it seems to take a bit out of my laptop, so I don’t want it to need to fight for resources with the other tasks.

Rise and Shine

My script schedules these every day, but does not schedule their daylight counterparts for morning. Why? Because I don’t care when the Sun rises. When I get up, I want the computer to act like the Sun has risen, regardless of whether it actually has. And because of that, the script can run the “bare” gsettings commands listed above when I terminate it, nice and straightforward.

Miscellany

Oh, and to work around my problem above of the setting not automatically propagating to all applications, I can open gnome-control-center after a delay, simulating my own manual behavior. I don’t love that, but it should mostly work until they fix the bug.

I don’t have any “smart” gadgets, myself. For those who do, though, if your system has a decent API, this approach would work well for managing exterior lights. Similar to my night/day needs, an exterior light becomes almost entirely useless during the day, but—depending on the situation—could dramatically improve safety.


Credits: The header image is untitled by an uncredited PxHere photographer, made available under the terms of the Creative Commons CC0 1.0 Universal Public Domain Dedication.