# Automatic Dark/Light Theme Switching on Sway with Guix

Source: https://gofranz.com/blog/automatic-dark-light-theme-switching-sway-guix/

I've been meaning to set up automatic theme switching for a while now. Manually toggling between dark and light themes gets old fast, especially when I'm working across different times of day. Enter darkman - a simple daemon that handles this automatically.

## What is Darkman?

[Darkman](https://darkman.whynothugo.nl/) is a framework for dark-mode and light-mode transitions. It automatically switches themes at sunrise and sunset based on your location, and lets you manually toggle when needed. The beauty is in its simplicity: it runs scripts when switching modes, so you can control exactly what changes.

## Guix Home Setup

On Guix, darkman integrates via a home service. Add this to your home configuration:

```scheme
(service home-darkman-service-type
         (home-darkman-configuration
          (latitude 38.7)
          (longitude -9.2)
          (use-geoclue? #f)))
```

Set your latitude and longitude to get accurate sunrise/sunset times. I disable geoclue since I don't need dynamic location tracking.

## What Gets Switched

Darkman will handle:

- **GTK applications**: LibreOffice, Thunar, file managers (Yaru-dark ↔ Yaru theme)
- **Foot terminal**: Instant color switching via UNIX signals
- **Dunst notifications**: Background and foreground colors

## The Implementation

Darkman executes scripts from two directories:
- `~/.local/share/dark-mode.d/` - runs when switching to dark mode
- `~/.local/share/light-mode.d/` - runs when switching to light mode

For GTK apps, two separate mechanisms are needed - not all applications respect both:

### 1. Portal/D-Bus (for modern apps)

```bash
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
gsettings set org.gnome.desktop.interface gtk-theme 'Yaru-dark'
```

The `color-scheme` setting broadcasts via D-Bus to the [FreeDesktop portal](https://flatpak.github.io/xdg-desktop-portal/) (`org.freedesktop.appearance.color-scheme`). Modern applications - Firefox, Chrome, VSCode, Electron apps - listen to this portal and switch automatically.

The `gtk-theme` setting tells GTK applications which theme to use (e.g., `Yaru-dark` vs `Yaru`). For light mode, use `prefer-light` and remove the `-dark` suffix from the theme name.

### 2. GTK-3 settings.ini (for legacy apps)

Some applications like Thunar read `~/.config/gtk-3.0/settings.ini` directly instead of using D-Bus:

```ini
[Settings]
gtk-theme-name = Yaru-dark
gtk-application-prefer-dark-theme = 1
```

The darkman script copies a template to this location:

```bash
TEMPLATE="$HOME/.local/share/gtk-themes/settings-dark.ini"
GTK3_CONFIG="$HOME/.config/gtk-3.0/settings.ini"
cp "$TEMPLATE" "$GTK3_CONFIG"
```

For light mode, set `gtk-theme-name = Yaru` and `gtk-application-prefer-dark-theme = 0`.

For the Foot terminal I run `foot --server` and connect with `footclient`. This lets me use signals for instant theme switching - one signal updates the server and all connected terminals without restart:

```bash
# Dark mode: SIGUSR1 switches to [colors] section
kill -SIGUSR1 $(pgrep -x foot) 2>/dev/null || true

# Light mode: SIGUSR2 switches to [colors2] section
kill -SIGUSR2 $(pgrep -x foot) 2>/dev/null || true
```

Your `foot.ini` just needs both color sections defined, with `initial-color-theme=1` to start dark.

## Usage

Once configured, darkman runs automatically:
- Switches to light mode at sunrise
- Switches to dark mode at sunset
- Manual toggle with `darkman toggle` (I bind this to `Mod+T` in Sway)

Test it works:

```bash
darkman toggle
```

Everything should switch instantly - GTK apps, terminal colors, notifications.

## Full Implementation

The complete setup with all scripts and configurations is in my [dotfiles repository](https://github.com/franzos/dotfiles).
