How to Create a Theme Switcher in Hyprland with Rofi (Part 6)
Learn to build a custom theme switcher for Hyprland with Rofi! Step-by-step guide to dynamic wallpapers, color schemes, and notifications.
This guide details the process of creating a custom theme switcher for the Hyprland window manager, leveraging Rofi for user interaction and a custom script to apply changes. The system allows users to select a wallpaper, which then dynamically updates the system's theme, including the wallpaper, terminal colors, and application themes.
System Overview and Setup
The core of this theme switching mechanism is a script, here named wallset, which takes a wallpaper image path as an argument. This script orchestrates several actions:
- Notification: It sends a notification to the user indicating that the theme is being changed.
- Wallpaper Application: It sets the chosen wallpaper using
swww(Simple Wayland Wallpaper Utility). The commandswww img --transition-type <type> --transition-step <steps> --transition-fps <fps> <image_path>is used, allowing for customizable transition effects, steps, and frame rates. - Color Generation: It utilizes
pywalto generate color schemes based on the selected wallpaper. Specific flags are used withpywal:-n: Skips setting the wallpaper (as it's already handled byswww).-s: Skips changing colors in terminals.-t: Skips changing colors in TTY.-e: Skips reloadingxrdb,i3,sway, orpolybar. These are omitted as the environment is Wayland.
- Application Theming:
- Neovim: An extension,
base64-pywal, is used to make Neovim adopt the generatedpywalcolors. This requires cloning the repository, building it, and adding a configuration line toinit.lua. Executingpython3 chad.pyrefreshes colors in open Neovim instances. - Spotify:
spicetifyis employed to adapt Spotify's theme to thepywalcolors. - Dribbbl: This component is mentioned but deferred for explanation in a separate context.
- Matugen: This tool, previously explained, generates Material You colors for various applications, including Hyprland, Waybar, and web applications. The configuration for these applications is stored in
~/.config/matugen/config.toml.
- Neovim: An extension,
- Wayland Compositor Reload:
hyprctl reloadis used to refresh Hyprland's configuration. - Notification Center Reload:
swaync-client -Ris executed to reload the Sway Notification Center, which also clears existing notifications. - Final Notification: A success message is displayed to the user, confirming that the wallpaper and theme have been applied.
Path Configuration
To ensure the wallset script is accessible system-wide, its directory, ~/lo/bin, must be added to the system's PATH environment variable. For Zsh users, this is done by adding the following line to ~/.zshrc:
export PATH="$HOME/lo/bin:$PATH"
For Bash users, the configuration would be added to ~/.bash_profile.
Additionally, environment variables like TERM (set to kitty in this example) and QT_QPA_PLATFORMTHEME (set to gtk3 for Qt applications) can be configured.
Creating the wallset Backend Script
The wallset script, located in ~/lo/bin, handles the actual theme application.
Argument Handling
The script first checks if a wallpaper image path has been provided as an argument. If not, it displays a usage message: Usage: <program_name> <path_to_image> and exits with a non-zero status code.
if [ -z "$1" ]; then
echo "Usage: $0 <path_to_image>"
exit 1
fi
The provided image path is stored in the image variable:
image="$1"
Script Execution Flow
- Notification:
notify-send "Changing theme" "Applying new wallpaper..." - Wallpaper Setting:
swww img --transition-type Center --transition-step 10 --transition-fps 60 "$image" - Pywal Color Generation:
Note: The original draft mentionswal -n -s -t -e --theme-name "$image" # Using image name for theme namepywalflags-n,-s,-t,-e. The example command includes--theme-name "$image"which is not a standardpywalflag for theme naming in this context, but rather a placeholder for a potential custom theme naming convention. - Neovim Refresh:
python3 ~/.config/nvim/base64-pywal/chad.py - Spotify Refresh:
spicetify update - Matugen Configuration:
matugen --config ~/.config/matugen/config.toml --wallpaper "$image" - Hyprland Reload:
hyprctl reload - Sway Notification Center Reload:
swaync-client -R - Success Notification:
notify-send "Theme Applied" "Wallpaper and theme updated successfully."
Integrating with Rofi
To enable theme switching via Rofi, a separate script, named wallify (or a similar user-chosen name), is created in ~/lo/bin. This script handles the user selection process.
Script Structure
- Store Current Directory: The script first saves the current working directory to a variable
CWDfor later use.CWD=$(pwd) - Change to Wallpaper Directory: It then changes the directory to the location of the wallpaper images. If this fails, the script exits.
cd ~/Pictures/Wallpapers || exit 1 - Set Internal Field Separator: The
IFSvariable is set to a newline character (\n) to correctly handle filenames with spaces.IFS=$'\n' - User Selection with Rofi: The script uses Rofi to present a list of available wallpapers (JPG and PNG files) to the user.
selected_wall=$(ls *.jpg *.png | rofi -dmenu -p "Choose Wallpaper: " -i)ls *.jpg *.png: Lists all files ending with.jpgor.pngin the current directory.rofi -dmenu -p "Choose Wallpaper: " -i: Runs Rofi in dmenu mode, displaying the list of files.-psets the prompt text, and-ienables case-insensitive matching.
- Apply Selected Theme: If a wallpaper is selected (i.e.,
selected_wallis not empty), thewallsetbackend script is called with the chosen wallpaper path.if [ -n "$selected_wall" ]; then ~/lo/bin/wallset "$selected_wall" fi - Return to Original Directory: Finally, the script changes back to the original working directory.
cd "$CWD" || exit 1
Making Scripts Executable
Both the wallset and wallify scripts must be made executable using the chmod command:
chmod +x ~/lo/bin/wallset
chmod +x ~/lo/bin/wallify
Keybind Configuration
To trigger the wallify script with a keyboard shortcut, users need to configure a keybind in their Hyprland configuration file (~/.config/hypr/hyprland.conf). For example, to use Super + R:
bind = $mainMod, R, exec, ~/lo/bin/wallify
After setting up these scripts and the keybind, pressing Super + R will launch Rofi, allowing the user to select a wallpaper. Upon selection, the wallset script will execute, applying the chosen wallpaper and updating the system's theme accordingly.
Introduction and Demonstration
Demonstrates the functionality of the theme switcher by selecting a wallpaper and observing system-wide changes, including notifications.
- The theme switcher applies changes based on a selected wallpaper.
- Notifications are displayed to confirm theme application.
- The tool can be named by the user (e.g., 'wallify', 'change theme').
Environment Setup: PATH and Variables
Explains the necessity of adding `/home/user/.local/bin` to the system's PATH for script execution and briefly touches upon terminal and QT/GTK theme settings.
- The directory
~/.local/binmust be added to the system's PATH. - For Zsh shell, modify
~/.zshrcwithexport PATH=$HOME/.local/bin:$PATH. - For Bash shell, modify
~/.bash_profile. TERMvariable sets the terminal emulator (e.g., Kitty).QT_QPA_PLATFORMTHEMEcan set GTK3 themes for QT applications.
The `wallset-backend` Script
Details the creation and functionality of the `wallset-backend` script, including argument handling, notification display, wallpaper setting, and color generation using `pywal`.
- The script is named
wallset-backendand placed in~/.local/bin. - It checks for a required image path argument; otherwise, it displays usage instructions.
- Notifications are sent using
notify-send. - Wallpapers are set using
swwwwith options for transitions. pywalis used to generate color schemes from the wallpaper.- Flags like
-n,-s,-t,-econtrolpywal's behavior (skip wallpaper, colors, TTY, xrdb reload).
Color Theming Integration
Explains how to integrate `pywal` colors with Neovim and Spicetify, and how `mako` generates Material You colors for various applications.
- A Neovim plugin (
base46-pywal) can applypywalcolors to the editor. - Spicetify can be used to theme Spotify with
pywalcolors. mako(ormateria-gen) generates Material You colors for applications defined in~/.config/mako/config.toml.- The web start page can also adopt Material You colors.
Refreshing Wayland and Notifications
Covers refreshing Wayland compositor (`Hyprland` or `Sway`) and the Sway notification center (`swaync`) after theme changes.
- Wayland compositors like Hyprland or Sway can be restarted using commands like
hyprctl reloadorswaymsg reload(ormod+r). - Sway notification center (
swaync) can be refreshed to clear notifications and reload its configuration.
Finalizing and Executing the Theme Switcher
Details the final success notification and the execution of the `wallset-backend` script with an example.
- A final notification confirms successful theme application.
- The script is executed by running
wallset-backend <path_to_image>. - Example path:
~/Pictures/Wallpapers/some_wallhaven_wallpaper.png.
Integration with Rofi
Explains how to make the script executable and integrate it with Rofi for a graphical selection interface.
- Make the script executable using
chmod +x ~/.local/bin/<script_name>. - The
roficommand is used to present a list of wallpapers. - The
walletscript (a wrapper) is executed by a keybind to launchrofi. - Internal field separator (
IFS) is set to newline to handle filenames with spaces. - The selected wallpaper path is passed to
wallset-backend.
The `wallet` Rofi Integration Script
Provides the core logic for the `wallet` script, which prepares the wallpaper list for Rofi and calls the backend script upon selection.
- The
walletscript navigates to the wallpaper directory. - It handles potential errors during directory changes.
- It iterates through
.jpgand.pngfiles to create a list for Rofi. echo -eandecho -nare used for formatting output.- The output is piped to
rofi -dmenufor user selection. - The selected wallpaper is passed to
wallset-backend. - The script returns to the original working directory.
