#!/bin/sh MODE="$1" get_color() { xrdb -get "$1" } hex_to_rgb_array() { printf "%d\n%d\n%d\n" "0x$(echo "$1" | cut -c2-3)" "0x$(echo "$1" | cut -c4-5)" "0x$(echo "$1" | cut -c6-7)" | jq -jc --slurp '.' } get_color_rgb_array() { hex_to_rgb_array "$(get_color "$1")" } mix_rgb() { R1="$(printf "%d" "0x$(echo "$1" | cut -c2-3)")" G1="$(printf "%d" "0x$(echo "$1" | cut -c4-5)")" B1="$(printf "%d" "0x$(echo "$1" | cut -c6-7)")" R2="$(printf "%d" "0x$(echo "$2" | cut -c2-3)")" G2="$(printf "%d" "0x$(echo "$2" | cut -c4-5)")" B2="$(printf "%d" "0x$(echo "$2" | cut -c6-7)")" printf "#" dc -e"$R1 $3 * $R2 1 $3 - * + 1 / p" | xargs printf "%02x" dc -e"$G1 $3 * $G2 1 $3 - * + 1 / p" | xargs printf "%02x" dc -e"$B1 $3 * $B2 1 $3 - * + 1 / p" | xargs printf "%02x" } switch_xrdb() { xrdb -override "$XDG_CONFIG_HOME/X11/$1" } switch_dunst() { cat "$XDG_CONFIG_HOME/dunst/base" - << EOF > "$XDG_CONFIG_HOME/dunst/dunstrc" frame_color = "$(get_color color0)" [urgency_low] background = "$(get_color background)" foreground = "$(get_color foreground)" timeout = 10 [urgency_normal] background = "$(get_color background)" foreground = "$(get_color foreground)" timeout = 10 [urgency_critical] background = "$(get_color color1)" foreground = "$(get_color background)" frame_color = "$(get_color color1)" timeout = 0 EOF } switch_zathura() { cat << EOF > "$XDG_CONFIG_HOME/zathura/colors" set default-bg "$(get_color background)" set statusbar-bg "$(get_color background)" set inputbar-bg "$(get_color background)" set completion-highlight-fg "$(get_color background)" set completion-bg "$(get_color background)" set notification-error-fg "$(get_color background)" set notification-warning-fg "$(get_color background)" set notification-fg "$(get_color background)" set recolor-lightcolor "$(get_color background)" set default-fg "$(get_color foreground)" set inputbar-fg "$(get_color foreground)" set completion-fg "$(get_color foreground)" set statusbar-fg "$(get_color foreground)" set recolor-darkcolor "$(get_color foreground)" set notification-error-bg "$(get_color color9)" set notification-warning-bg "$(get_color color9)" set completion-highlight-bg "$(get_color color9)" set highlight-color "$(get_color color9)" set highlight-active-color "$(get_color color13)" set notification-bg "$(get_color color13)" EOF } switch_gtk() { GTK_3_SETTINGS_INI="$XDG_CONFIG_HOME/gtk-3.0/settings.ini" GTK_4_SETTINGS_ENV="$XDG_CONFIG_HOME/gtk-4.0/env" if [ $1 = "light" ]; then sed 's/^\(export\s\+GTK_THEME=.\+\)-Dark\(.*\)$/\1-Light\2/g' -i "$GTK_4_SETTINGS_ENV" sed "s/-Dark/-Light/" -i "$GTK_3_SETTINGS_INI" sed "s/gtk-application-prefer-dark-theme.*/gtk-application-prefer-dark-theme=false/" -i "$GTK_3_SETTINGS_INI" else sed 's/^\(export\s\+GTK_THEME=.\+\)-Light\(.*\)$/\1-Dark\2/g' -i "$GTK_4_SETTINGS_ENV" sed "s/-Light/-Dark/" -i "$GTK_3_SETTINGS_INI" sed "s/gtk-application-prefer-dark-theme.*/gtk-application-prefer-dark-theme=true/" -i "$GTK_3_SETTINGS_INI" fi grep gtk-theme-name "$GTK_3_SETTINGS_INI" | cut -f2 -d= | xargs xfconf-query -c xsettings -p /Net/ThemeName -s } switch_fcitx5() { accent="$(get_color color0)" cat "$XDG_DATA_HOME/fcitx5/themes/loek/base.conf" - << EOF > "$XDG_DATA_HOME/fcitx5/themes/loek/theme.conf" [InputPanel] NormalColor=$(get_color foreground) HighlightCandidateColor=$(get_color background) HighlightColor=$(get_color color13) HighlightBackgroundColor=$(get_color background) [InputPanel/Background] Color=$(get_color background) BorderColor=${accent} [InputPanel/Highlight] Color=${accent} [Menu/Background] Color=$(get_color background) [Menu] NormalColor=$(get_color foreground) [Menu/Highlight] Color=${accent} [Menu/Separator] Color=$(get_color color7) EOF } switch_chrome() { cd ~/.cache/wal/chromium rm -f 'Cached Theme.pak' 'bg.png' 'manifest.json' convert -size 100x100 "xc:$(get_color background)" bg.png BG_ALT=$(mix_rgb $(get_color color7) $(get_color background) '0.20') FG_ALT=$(mix_rgb $(get_color color15) $(get_color foreground) '0.60') jq -nc \ --argjson bg "$(get_color_rgb_array background)" \ --argjson bg_alt "$(hex_to_rgb_array $BG_ALT)" \ --argjson fg "$(get_color_rgb_array foreground)" \ --argjson fg_alt "$(hex_to_rgb_array $FG_ALT)" \ '{ "description": "colorscheme generated by mode", "manifest_version": 2, "name": "mode theme", "theme": { "images": { "theme_frame": "bg.png" }, "colors": { "frame": $bg, "button_background": $fg, "ntp_background": $bg, "ntp_text": $bg, "toolbar": $bg_alt, "toolbar_button_icon": $fg, "tab_background_text": $fg_alt, "tab_background_text_inactive": $fg_alt, "tab_background_text_incognito": $fg_alt, "tab_background_text_incognito_inactive": $fg_alt, "bookmark_text": $fg, "tab_text": $fg }, "tints": { "buttons": [ -1, -1, -1 ], "frame_inactive": [ -1, -1, -1 ], "frame_incognito": [ -1, -1, -1 ], "frame_incognito_inactive": [ -1, -1, -1 ] } }, "version": "2" }' > manifest.json } switch_polybar() { cat << EOF > "$XDG_CONFIG_HOME/polybar/colors.ini" [color] bg = \${xrdb:background:$(get_color background)} fg = \${xrdb:foreground:$(get_color foreground)} fg-alt = \${xrdb:background:$(get_color background)} fg-half = \${xrdb:color8:$(get_color color8)} alpha = #00000000 ; vim:ft=dosini EOF } switch_vim_lightline() { cat - "$XDG_CONFIG_HOME/nvim/lightline-base.vim" << EOF > "$XDG_CONFIG_HOME/nvim/lightline.vim" let s:bg = [ '$(get_color background)', 'NONE' ] let s:fg = [ '$(get_color foreground)', 'NONE' ] let s:mode = [ '$(get_color color0)', 'NONE' ] let s:faint = [ '$(get_color color8)', 'NONE' ] let s:none = [ 'NONE', 'NONE' ] let s:test = [ '#ff00ff', 'NONE' ] EOF } switch_vim_terminal() { cat << EOF > "$XDG_CONFIG_HOME/nvim/termcolors.vim" let g:terminal_color_0 = '$(get_color color0)' let g:terminal_color_1 = '$(get_color color1)' let g:terminal_color_2 = '$(get_color color2)' let g:terminal_color_3 = '$(get_color color3)' let g:terminal_color_4 = '$(get_color color4)' let g:terminal_color_5 = '$(get_color color5)' let g:terminal_color_6 = '$(get_color color6)' let g:terminal_color_7 = '$(get_color color7)' let g:terminal_color_8 = '$(get_color color8)' let g:terminal_color_9 = '$(get_color color9)' let g:terminal_color_10 = '$(get_color color10)' let g:terminal_color_11 = '$(get_color color11)' let g:terminal_color_12 = '$(get_color color12)' let g:terminal_color_13 = '$(get_color color13)' let g:terminal_color_14 = '$(get_color color14)' let g:terminal_color_15 = '$(get_color color15)' EOF } switch_discord() { cat << EOF > "$XDG_CONFIG_HOME/BetterDiscord/themes/mode.theme.css" /** * @name mode * @author mode * @version 0 */ /* AUTOMATICALLY GENERATED, DO NOT EDIT */ .theme-dark, .theme-light { --background-primary: $(get_color background); --background-secondary: $(get_color background); --background-secondary-alt: $(get_color background); --text-primary: $(get_color foreground); --text-secondary: $(get_color color15); --accent: $(get_color color4); --accent-alt: $(get_color color12); --error: $(get_color color1); --error-alt: $(get_color color9); } .theme-dark { --background-tertiary: $(mix_rgb $(get_color background) '#000000' '0.7'); } .theme-light { --background-tertiary: $(get_color background); } EOF } reload_terms() { escape_msgs="$(cat << EOF | tr -d '\n' \033]11;$(get_color background)\007 \033]10;$(get_color foreground)\007 \033]12;$(get_color foreground)\007 \033]14;$(get_color background)\007 \033]13;$(get_color foreground)\007 \033]17;$(get_color color8)\007 \033]708;$(get_color background)\007 \033]4;0;$(get_color color0)\007 \033]4;1;$(get_color color1)\007 \033]4;2;$(get_color color2)\007 \033]4;3;$(get_color color3)\007 \033]4;4;$(get_color color4)\007 \033]4;5;$(get_color color5)\007 \033]4;6;$(get_color color6)\007 \033]4;7;$(get_color color7)\007 \033]4;8;$(get_color color8)\007 \033]4;9;$(get_color color9)\007 \033]4;10;$(get_color color10)\007 \033]4;11;$(get_color color11)\007 \033]4;12;$(get_color color12)\007 \033]4;13;$(get_color color13)\007 \033]4;14;$(get_color color14)\007 \033]4;15;$(get_color color15)\007 EOF )" find /dev/pts -exec sh -c "printf \"$escape_msgs\" > {}" \; 2> /dev/null } reload_dunst() { killall dunst fork dunst } reload_polybar() { fork polybar-msg cmd restart } reload_fcitx5() { fork fcitx5 -rd } reload_gtk() { # this is max jank but xfsettingsd does other things besides live gtk theme # reloading, and i don't like having it running constantly because it fucks # up fcitx5 and xbindkeys ( fork xfsettingsd sleep 1 killall xfsettingsd ) } reload_nvim() { nvr --serverlist | while read -r nvim_socket ; do fork nvr --nostart --servername "$nvim_socket" -c 'source $XDG_CONFIG_HOME/nvim/mode.vim' done } switch_cfgs() { echo "switching to $1 mode..." # xrdb needs to complete first, as the rest of the color schemes are derived # from querying xrdb for colors switch_xrdb $1 switch_dunst $1 & switch_zathura $1 & switch_gtk $1 & switch_fcitx5 $1 & switch_chrome $1 & switch_polybar $1 & switch_vim_lightline $1 & switch_discord $1 & switch_vim_terminal $1 & mkdir -p "$XDG_DATA_HOME/mode" echo $1 > "$XDG_DATA_HOME/mode/active" rm -f "$XDG_DATA_HOME/mode/dark" "$XDG_DATA_HOME/mode/light" touch "$XDG_DATA_HOME/mode/$1" wait $(jobs -rp) } [ $MODE = "restore" ] && MODE="$(cat "$XDG_DATA_HOME/mode/active")" [ $MODE = "dark" -o $MODE = "light" ] && switch_cfgs $MODE reload_apps() { echo "reloading programs..." reload_polybar & reload_dunst & reload_terms & reload_fcitx5 & reload_gtk & reload_nvim & rwall & wait $(jobs -rp) } reload_apps