Zeljko's Blog

Managing dark and light theme in Sway

Created: 2024-11-05
Last Modified: 2025-01-29

I am again using Linux, a real operating system. But the even better part is a usable window manager which does not stand in my way, Sway. It let’s me manage windows efficiently and it’s very good at it. But many features are not built in, it comes more barebone. One feature I miss is a dark and light mode toggle. Something that switches the theme to a dark or light mode globally.

The reason for why I want a light and dark mode is simple, it’s related to the brightness of my office room. My office room is very bright during the day when the sun shines and less bright during the late hours. This changes a little bit during the winter but generally stays true. Because of that, I like to have a light theme during the day time and dark theme during the hours when the sun is not shining so much. It helps me with eye strain a lot and the reflection from the light bouncing off from white surfaces.

This is a problem I wanted to solve for myself. Having a script which helps me manage a global dark and light theme!

But before starting I had to decide on a theme which is available for as many applications as possible and looks good. The obvious choice is of course Catpuccin because in 2024 pastel colours are the hot stuff. Back in 2018 it was good old Gruvbox or even Solarized.

I choose Catpuccin Latte and Mocha. Hence, I applied the theme(s) to all my applications for which the theme is available.

Lastly, I needed some way to make this somewhat automated. For that a shell script sounded like the right choice! And I think it still is. So I hacked something together!

I would like to configure for each component how to load a dark theme, how to load a light theme and optionally how to apply that theme. The distinction between the three steps is helpfull. Some software automatically applies the theme on change. For example when setting the GTK theme via gsettings. For others it is not necessary, like for wofi because the programm picks up the colors on each startup.

So it’s somehow clear. Apply light, apply dark and maybe if we need it, an apply theme. This sounds like two or three functions to me. Great. But here comes a very nice thing about Bash. Bash has a really nice way of getting all declared functions. The following code sample shows how:

$ function foobar() { echo "hello"; }
$ function foobar2() { echo "hello"; }
$ declare -F
declare -f foobar
declare -f foobar2

This can be parsed very easy with declare -F | awk '{ print($3) }'.

In the end it’s possible to iterate over all declared functions! To finish it up, I just need to adhere to a given naming pattern. So I decided to keep it simple, and the result is as follows:

function programm_apply() {
    echo "apply the theme, this is totally optional"
}

function programm_dark() {
    echo "do things to set the dark theme in place"
}

function programm_light() {
    echo "do things to set the light theme in place"
}

I implemented in the end a toggle in my script to automatically choose the right functions and that’s it!

The full script for that can be found at https://github.com/zeljkobekcic/toggle-theme/