Skip to content

Wallpaper Templates

The templates feature provides automatic theming for your desktop applications. When the wallpaper changes, pyprland:

  1. Extracts dominant colors from the wallpaper image
  2. Generates a Material Design-inspired color palette
  3. Processes your template files, replacing color placeholders with actual values
  4. Runs optional post_hook commands to apply the changes

This creates a unified color scheme across your terminal, window borders, GTK apps, and other tools - all derived from your wallpaper.

TIP

If you're migrating from matugen or pywal, your existing templates should work with minimal changes.

Commands

Loading commands...

Using the color command

The color command allows testing the palette with a specific color instead of extracting from the wallpaper:

  • pypr color "#ff0000" - Re-generate the templates with the given color
  • pypr color "#ff0000" neutral - Re-generate the templates with the given color and color scheme (color filter)

Using the palette command

The palette command shows available color template variables:

  • pypr palette - Show palette using colors from current wallpaper
  • pypr palette "#ff0000" - Show palette for a specific color
  • pypr palette json - Output palette in JSON format

Configuration

Loading configuration...

templates

Enables automatic theming by generating config files from templates using colors extracted from the wallpaper.

toml
[wallpapers.templates.hyprland]
input_path = "~/color_configs/hyprlandcolors.sh"
output_path = "/tmp/hyprlandcolors.sh"
post_hook = "sh /tmp/hyprlandcolors.sh"

TIP

Mostly compatible with matugen template syntax.

color_scheme

Optional modification of the base color used in the templates. One of:

  • pastel - a bit more washed colors
  • fluo or fluorescent - for high color saturation
  • neutral - for low color saturation
  • earth - a bit more dark, a bit less blue
  • vibrant - for moderate to high saturation
  • mellow - for lower saturation

variant

Changes the algorithm used to pick the primary, secondary and tertiary colors.

  • islands - uses the 3 most popular colors from the wallpaper image

By default it will pick the "main" color and shift the hue to get the secondary and tertiary colors.

Template Configuration

Each template requires an input_path (template file with placeholders) and output_path (where to write the result):

toml
[wallpapers.templates.hyprland]
input_path = "~/color_configs/hyprlandcolors.sh"
output_path = "/tmp/hyprlandcolors.sh"
post_hook = "sh /tmp/hyprlandcolors.sh"  # optional: runs after this template
OptionRequiredDescription
input_pathYesPath to template file containing {{placeholders}}
output_pathYesWhere to write the processed output
post_hookNoCommand to run after this specific template is generated

NOTE

post_hook vs post_command: The post_hook runs after each individual template is generated. The global post_command runs once after the wallpaper is set and all templates are processed.

Template Syntax

Use double curly braces to insert color values:

txt
{{colors.<color_name>.<variant>.<format>}}
PartOptionsDescription
color_nameSee color referenceThe color role (e.g., primary, surface)
variantdefault, dark, lightWhich theme variant to use
formathex, hex_stripped, rgb, rgbaOutput format

Examples:

txt
{{colors.primary.default.hex}}           → #6495ED
{{colors.primary.default.hex_stripped}}  → 6495ED
{{colors.primary.dark.rgb}}              → rgb(100, 149, 237)
{{colors.surface.light.rgba}}            → rgba(250, 248, 245, 1.0)

Shorthand: {{colors.primary.default}} is equivalent to {{colors.primary.default.hex}}

The default variant automatically selects dark or light based on theme detection.

Special Variables

In addition to colors, these variables are available in templates:

VariableDescriptionExample Value
{{image}}Full path to the current wallpaper/home/user/Pictures/sunset.jpg
{{scheme}}Detected themedark or light

Color Formats

FormatExampleTypical Use
hex#6495EDMost applications, CSS
hex_stripped6495EDHyprland configs, apps that don't want #
rgbrgb(100, 149, 237)CSS, GTK
rgbargba(100, 149, 237, 1.0)CSS with opacity

Filters

Filters modify color values. Use the pipe (|) syntax:

txt
{{colors.primary.default.hex | filter_name: argument}}

set_alpha - Add transparency to a color

Converts the color to RGBA format with the specified alpha value (0.0 to 1.0):

txt
Template:  {{colors.primary.default.hex | set_alpha: 0.5}}
Output:    rgba(100, 149, 237, 0.5)

Template:  {{colors.surface.default.hex | set_alpha: 0.8}}
Output:    rgba(26, 22, 18, 0.8)

set_lightness - Adjust color brightness

Changes the lightness by a percentage (-100 to 100). Positive values lighten, negative values darken:

txt
Template:  {{colors.primary.default.hex | set_lightness: 20}}
Output:    #8AB4F8  (20% lighter)

Template:  {{colors.primary.default.hex | set_lightness: -20}}
Output:    #3A5980  (20% darker)

Theme Detection

The default color variant automatically adapts to your system theme. Detection order:

  1. gsettings (GNOME/GTK): gsettings get org.gnome.desktop.interface color-scheme
  2. darkman: darkman get
  3. Fallback: defaults to dark if neither is available

You can check the detected theme using the {{scheme}} variable in your templates.

Color Reference

Colors follow the Material Design 3 color system, organized by role:

Primary Colors - Main accent color derived from the wallpaper

ColorDescription
primaryMain accent color
on_primaryText/icons displayed on primary color
primary_containerLess prominent container using primary hue
on_primary_containerText/icons on primary container
primary_fixedFixed primary that doesn't change with theme
primary_fixed_dimDimmer variant of fixed primary
on_primary_fixedText on fixed primary
on_primary_fixed_variantVariant text on fixed primary

Secondary Colors - Complementary accent (hue-shifted from primary)

ColorDescription
secondarySecondary accent color
on_secondaryText/icons on secondary
secondary_containerContainer using secondary hue
on_secondary_containerText on secondary container
secondary_fixed, secondary_fixed_dimFixed variants
on_secondary_fixed, on_secondary_fixed_variantText on fixed

Tertiary Colors - Additional accent (hue-shifted opposite of secondary)

ColorDescription
tertiaryTertiary accent color
on_tertiaryText/icons on tertiary
tertiary_containerContainer using tertiary hue
on_tertiary_containerText on tertiary container
tertiary_fixed, tertiary_fixed_dimFixed variants
on_tertiary_fixed, on_tertiary_fixed_variantText on fixed

Surface Colors - Backgrounds and containers

ColorDescription
surfaceDefault background
surface_brightBrighter surface variant
surface_dimDimmer surface variant
surface_container_lowestLowest emphasis container
surface_container_lowLow emphasis container
surface_containerDefault container
surface_container_highHigh emphasis container
surface_container_highestHighest emphasis container
on_surfaceText/icons on surface
surface_variantAlternative surface
on_surface_variantText on surface variant
backgroundApp background
on_backgroundText on background

Error Colors - Error states and alerts

ColorDescription
errorError color (red hue)
on_errorText on error
error_containerError container background
on_error_containerText on error container

Utility Colors

ColorDescription
sourceOriginal extracted color (unmodified)
outlineBorders and dividers
outline_variantSubtle borders
inverse_primaryPrimary for inverse surfaces
inverse_surfaceInverse surface color
inverse_on_surfaceText on inverse surface
surface_tintTint overlay for elevation
scrimOverlay for modals/dialogs
shadowShadow color
whitePure white

ANSI Terminal Colors - Standard terminal color palette

ColorDescription
redANSI red
greenANSI green
yellowANSI yellow
blueANSI blue
magentaANSI magenta
cyanANSI cyan

Examples

Hyprland Window Borders

Config (pyprland.toml):

toml
[wallpapers.templates.hyprland]
input_path = "~/color_configs/hyprlandcolors.sh"
output_path = "/tmp/hyprlandcolors.sh"
post_hook = "sh /tmp/hyprlandcolors.sh"

Template (~/color_configs/hyprlandcolors.sh):

txt
hyprctl keyword general:col.active_border "rgb({{colors.primary.default.hex_stripped}}) rgb({{colors.tertiary.default.hex_stripped}}) 30deg"
hyprctl keyword general:col.inactive_border "rgb({{colors.surface_variant.default.hex_stripped}})"
hyprctl keyword decoration:shadow:color "rgba({{colors.shadow.default.hex_stripped}}ee)"

Output (after processing with a blue-toned wallpaper):

sh
hyprctl keyword general:col.active_border "rgb(6495ED) rgb(ED6495) 30deg"
hyprctl keyword general:col.inactive_border "rgb(3D3D3D)"
hyprctl keyword decoration:shadow:color "rgba(000000ee)"

Kitty Terminal Theme

Config:

toml
[wallpapers.templates.kitty]
input_path = "~/color_configs/kitty_theme.conf"
output_path = "~/.config/kitty/current-theme.conf"
post_hook = "kill -SIGUSR1 $(pgrep kitty) 2>/dev/null || true"

Template (~/color_configs/kitty_theme.conf):

sh
# Auto-generated theme from wallpaper: {{image}}
# Scheme: {{scheme}}

foreground {{colors.on_background.default.hex}}
background {{colors.background.default.hex}}
cursor {{colors.primary.default.hex}}
cursor_text_color {{colors.on_primary.default.hex}}
selection_foreground {{colors.on_primary.default.hex}}
selection_background {{colors.primary.default.hex}}

# ANSI colors
color0 {{colors.surface.default.hex}}
color1 {{colors.red.default.hex}}
color2 {{colors.green.default.hex}}
color3 {{colors.yellow.default.hex}}
color4 {{colors.blue.default.hex}}
color5 {{colors.magenta.default.hex}}
color6 {{colors.cyan.default.hex}}
color7 {{colors.on_surface.default.hex}}

GTK4 CSS Theme

Config:

toml
[wallpapers.templates.gtk4]
input_path = "~/color_configs/gtk.css"
output_path = "~/.config/gtk-4.0/colors.css"

Template:

css
/* Auto-generated from wallpaper */
@define-color accent_bg_color {{colors.primary.default.hex}};
@define-color accent_fg_color {{colors.on_primary.default.hex}};
@define-color window_bg_color {{colors.surface.default.hex}};
@define-color window_fg_color {{colors.on_surface.default.hex}};
@define-color headerbar_bg_color {{colors.surface_container.default.hex}};
@define-color card_bg_color {{colors.surface_container_low.default.hex}};
@define-color view_bg_color {{colors.background.default.hex}};
@define-color popover_bg_color {{colors.surface_container_high.default.hex}};

/* With transparency */
@define-color sidebar_bg_color {{colors.surface_container.default.hex | set_alpha: 0.95}};

JSON Export (for external tools)

Config:

toml
[wallpapers.templates.json]
input_path = "~/color_configs/colors.json"
output_path = "~/.cache/current-colors.json"
post_hook = "notify-send 'Theme Updated' 'New colors from wallpaper'"

Template:

json
{
  "scheme": "{{scheme}}",
  "wallpaper": "{{image}}",
  "colors": {
    "primary": "{{colors.primary.default.hex}}",
    "secondary": "{{colors.secondary.default.hex}}",
    "tertiary": "{{colors.tertiary.default.hex}}",
    "background": "{{colors.background.default.hex}}",
    "surface": "{{colors.surface.default.hex}}",
    "error": "{{colors.error.default.hex}}"
  }
}

Troubleshooting

For general pyprland issues, see the Troubleshooting page.

Template not updating?

  • Verify input_path exists and is readable
  • Check pyprland logs:
    • Systemd: journalctl --user -u pyprland -f
    • exec-once: Check your log file (e.g., tail -f ~/pypr.log)
  • Enable debug logging with --debug or --debug <logfile> (see Getting Started)
  • Ensure the wallpapers plugin is loaded in your config

Colors look wrong or washed out?

Theme detection not working?

  • Install darkman or ensure gsettings is available
  • Force a theme by using .dark or .light variants instead of .default

post_hook not running?

  • Commands run asynchronously; check for errors in logs
  • Ensure the command is valid and executable
  • Enable debug logging to see command execution details