better theme script
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
- kvantum: kvantummanager --set catppuccin-mocha-"$flavor"
|
- kvantum: kvantummanager --set catppuccin-mocha-"$flavor"
|
||||||
|
(a kvantum window will pop out if such theme is not installed)
|
||||||
|
|
||||||
- nwg-look: edit $HOME/.local/share/nwg-look/gsettings
|
- nwg-look: edit $HOME/.local/share/nwg-look/gsettings
|
||||||
nwg-look -a
|
nwg-look -a
|
||||||
@@ -17,14 +18,14 @@
|
|||||||
- waybar: edit $HOME/.config/waybar/style.css
|
- waybar: edit $HOME/.config/waybar/style.css
|
||||||
waybar-toggle.sh
|
waybar-toggle.sh
|
||||||
|
|
||||||
- ohmyposh: edit $HOME/.config/posh_theme.omp.json
|
- oh-my-posh: edit $HOME/.config/posh_theme.omp.json
|
||||||
|
|
||||||
- fastfetch: edit $HOME/.config/fish/post.d/fetch.fish
|
- fastfetch: edit $HOME/.config/fish/post.d/fetch.fish
|
||||||
|
|
||||||
- mako: edit $HOME/.config/mako/config
|
- mako: edit $HOME/.config/mako/config
|
||||||
makoctl reload
|
makoctl reload
|
||||||
|
|
||||||
- yazi: cp "$path"/../.yazi-themes/catppuccin-mocha-"$flavor".toml ~/.config/yazi/theme.toml
|
- yazi: cp -f "$path"/../.yazi-themes/catppuccin-mocha-"$flavor".toml ~/.config/yazi/theme.toml
|
||||||
|
|
||||||
- wlogout: edit $HOME/.config/wlogout/style.css
|
- wlogout: edit $HOME/.config/wlogout/style.css
|
||||||
edit $HOME/.config/wlogout/icons/*.svg
|
edit $HOME/.config/wlogout/icons/*.svg
|
||||||
@@ -36,30 +37,36 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shutil
|
import shutil
|
||||||
|
import argparse
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
FLAVOR_NAME_PLACEHOLDER = "<FLAVOR_NAME>"
|
FLAVOR_NAME_PLACEHOLDER = "<FLAVOR_NAME>"
|
||||||
FLAVOR_HEX_PLACEHOLDER = "<FLAVOR_HEX>"
|
FLAVOR_HEX_PLACEHOLDER = "<FLAVOR_HEX>"
|
||||||
|
|
||||||
CATPPUCIN_MOCHA_PALETTE = {
|
|
||||||
"rosewater": "f5e0dc",
|
PALETTES = {
|
||||||
"flamingo": "f2cdcd",
|
"catppuccin-mocha": {
|
||||||
"pink": "f5c2e7",
|
"rosewater": "f5e0dc",
|
||||||
"mauve": "cba6f7",
|
"flamingo": "f2cdcd",
|
||||||
"red": "f38ba8",
|
"pink": "f5c2e7",
|
||||||
"maroon": "eba0ac",
|
"mauve": "cba6f7",
|
||||||
"peach": "fab387",
|
"red": "f38ba8",
|
||||||
"yellow": "f9e2af",
|
"maroon": "eba0ac",
|
||||||
"green": "a6e3a1",
|
"peach": "fab387",
|
||||||
"teal": "94e2d5",
|
"yellow": "f9e2af",
|
||||||
"sky": "89dceb",
|
"green": "a6e3a1",
|
||||||
"sapphire": "74c7ec",
|
"teal": "94e2d5",
|
||||||
"blue": "89b4fa",
|
"sky": "89dceb",
|
||||||
"lavender": "b4befe"}
|
"sapphire": "74c7ec",
|
||||||
|
"blue": "89b4fa",
|
||||||
|
"lavender": "b4befe",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
CURRENT_DIR = Path(__file__).resolve().parent.resolve()
|
CURRENT_DIR = Path(__file__).resolve().parent.resolve()
|
||||||
|
|
||||||
|
|
||||||
def apply_flavor(file_path: Path, flavor: str):
|
def replace_placeholders(file_path: Path, palette: dict[str, str], flavor: str):
|
||||||
print(f"Applying flavor {flavor} to {file_path}")
|
print(f"Applying flavor {flavor} to {file_path}")
|
||||||
|
|
||||||
if not file_path.exists():
|
if not file_path.exists():
|
||||||
@@ -70,7 +77,7 @@ def apply_flavor(file_path: Path, flavor: str):
|
|||||||
content = file.read()
|
content = file.read()
|
||||||
|
|
||||||
content = content.replace(FLAVOR_NAME_PLACEHOLDER, flavor)
|
content = content.replace(FLAVOR_NAME_PLACEHOLDER, flavor)
|
||||||
content = content.replace(FLAVOR_HEX_PLACEHOLDER, CATPPUCIN_MOCHA_PALETTE[flavor])
|
content = content.replace(FLAVOR_HEX_PLACEHOLDER, palette[flavor])
|
||||||
|
|
||||||
with file_path.open('w') as file:
|
with file_path.open('w') as file:
|
||||||
file.write(content)
|
file.write(content)
|
||||||
@@ -98,13 +105,13 @@ def copy_template(src: Path, dist_dir: Path | None) -> Path:
|
|||||||
return dist
|
return dist
|
||||||
|
|
||||||
|
|
||||||
def change_kvantum(flavor):
|
def _change_kvantum(_, flavor):
|
||||||
os.system(f'kvantummanager --set catppuccin-mocha-{flavor}')
|
os.system(f'kvantummanager --set catppuccin-mocha-{flavor}')
|
||||||
# execute twice to ensure the theme is installed AND applied
|
# execute twice to ensure the theme is installed AND applied
|
||||||
os.system(f'kvantummanager --set catppuccin-mocha-{flavor}')
|
os.system(f'kvantummanager --set catppuccin-mocha-{flavor}')
|
||||||
|
|
||||||
|
|
||||||
def change_nwglook(flavor):
|
def _change_nwglook(_, flavor):
|
||||||
lines: list[str] = []
|
lines: list[str] = []
|
||||||
with Path.home().joinpath('.local', 'share', 'nwg-look', 'gsettings').open('r') as file:
|
with Path.home().joinpath('.local', 'share', 'nwg-look', 'gsettings').open('r') as file:
|
||||||
content = file.read()
|
content = file.read()
|
||||||
@@ -122,183 +129,220 @@ def change_nwglook(flavor):
|
|||||||
os.system('nwg-look -a')
|
os.system('nwg-look -a')
|
||||||
|
|
||||||
|
|
||||||
def change_eww(flavor):
|
def _change_eww(palette: dict[str, str], flavor: str):
|
||||||
eww_template = Path.home().joinpath('.config', 'eww', 'eww.scss.template')
|
eww_template = Path.home().joinpath('.config', 'eww', 'eww.scss.template')
|
||||||
eww_dist = copy_template(eww_template, Path.home().joinpath('.config', 'eww'))
|
eww_dist = copy_template(eww_template, Path.home().joinpath('.config', 'eww'))
|
||||||
apply_flavor(eww_dist, flavor)
|
replace_placeholders(eww_dist, palette, flavor)
|
||||||
|
|
||||||
os.system('eww reload')
|
os.system('eww reload')
|
||||||
|
|
||||||
|
|
||||||
def change_hypr(flavor):
|
def _change_hypr(palette: dict[str, str], flavor: str):
|
||||||
hypr_template = Path.home().joinpath('.config', 'hypr', 'hyprland', 'colors.conf.template')
|
hypr_template = Path.home().joinpath('.config', 'hypr', 'hyprland', 'colors.conf.template')
|
||||||
hypr_dist = copy_template(hypr_template, Path.home().joinpath('.config', 'hypr', 'hyprland'))
|
hypr_dist = copy_template(hypr_template, Path.home().joinpath('.config', 'hypr', 'hyprland'))
|
||||||
apply_flavor(hypr_dist, flavor)
|
replace_placeholders(hypr_dist, palette, flavor)
|
||||||
|
|
||||||
os.system('hyprctl reload')
|
os.system('hyprctl reload')
|
||||||
|
|
||||||
|
|
||||||
def change_rofi(flavor):
|
def _change_rofi(palette: dict[str, str], flavor: str):
|
||||||
rofi_template = Path.home().joinpath('.config', 'rofi', 'config.rasi.template')
|
rofi_template = Path.home().joinpath('.config', 'rofi', 'config.rasi.template')
|
||||||
rofi_dist = copy_template(rofi_template, Path.home().joinpath('.config', 'rofi'))
|
rofi_dist = copy_template(rofi_template, Path.home().joinpath('.config', 'rofi'))
|
||||||
apply_flavor(rofi_dist, flavor)
|
replace_placeholders(rofi_dist, palette, flavor)
|
||||||
|
|
||||||
|
|
||||||
def change_waybar(flavor):
|
def _change_waybar(palette: dict[str, str], flavor: str):
|
||||||
waybar_template = Path.home().joinpath('.config', 'waybar', 'style.css.template')
|
waybar_template = Path.home().joinpath('.config', 'waybar', 'style.css.template')
|
||||||
waybar_dist = copy_template(waybar_template, Path.home().joinpath('.config', 'waybar'))
|
waybar_dist = copy_template(waybar_template, Path.home().joinpath('.config', 'waybar'))
|
||||||
apply_flavor(waybar_dist, flavor)
|
replace_placeholders(waybar_dist, palette, flavor)
|
||||||
os.system('waybar-toggle.sh')
|
os.system('waybar-toggle.sh')
|
||||||
|
|
||||||
|
|
||||||
def change_ohmyposh(flavor):
|
def _change_ohmyposh(palette: dict[str, str], flavor: str):
|
||||||
posh_template = Path.home().joinpath('.config', 'posh_theme.omp.json.template')
|
posh_template = Path.home().joinpath('.config', 'posh_theme.omp.json.template')
|
||||||
posh_dist = copy_template(posh_template, Path.home().joinpath('.config'))
|
posh_dist = copy_template(posh_template, Path.home().joinpath('.config'))
|
||||||
apply_flavor(posh_dist, flavor)
|
replace_placeholders(posh_dist, palette, flavor)
|
||||||
|
|
||||||
|
|
||||||
def change_fastfetch(flavor):
|
def _change_fastfetch(palette: dict[str, str], flavor: str):
|
||||||
fetch_template = Path.home().joinpath('.config', 'fish', 'post.d', 'fetch.fish.template')
|
fetch_template = Path.home().joinpath('.config', 'fish', 'post.d', 'fetch.fish.template')
|
||||||
fetch_dist = copy_template(fetch_template, Path.home().joinpath('.config', 'fish', 'post.d'))
|
fetch_dist = copy_template(fetch_template, Path.home().joinpath('.config', 'fish', 'post.d'))
|
||||||
apply_flavor(fetch_dist, flavor)
|
replace_placeholders(fetch_dist, palette, flavor)
|
||||||
|
|
||||||
|
|
||||||
def change_mako(flavor):
|
def _change_mako(palette: dict[str, str], flavor: str):
|
||||||
mako_template = Path.home().joinpath('.config', 'mako', 'config.template')
|
mako_template = Path.home().joinpath('.config', 'mako', 'config.template')
|
||||||
mako_dist = copy_template(mako_template, Path.home().joinpath('.config', 'mako'))
|
mako_dist = copy_template(mako_template, Path.home().joinpath('.config', 'mako'))
|
||||||
apply_flavor(mako_dist, flavor)
|
replace_placeholders(mako_dist, palette, flavor)
|
||||||
|
|
||||||
os.system('makoctl reload')
|
os.system('makoctl reload')
|
||||||
|
|
||||||
|
|
||||||
def change_yazi(flavor):
|
def _change_yazi(_, flavor):
|
||||||
yazi_template = CURRENT_DIR / '..' / '.yazi-themes' / f'catppuccin-mocha-{flavor}.toml'
|
yazi_template = CURRENT_DIR / '..' / '.yazi-themes' / f'catppuccin-mocha-{flavor}.toml'
|
||||||
yazi_dist = Path.home().joinpath('.config', 'yazi', 'theme.toml')
|
yazi_dist = Path.home().joinpath('.config', 'yazi', 'theme.toml')
|
||||||
shutil.copyfile(yazi_template, yazi_dist, follow_symlinks=True)
|
shutil.copyfile(yazi_template, yazi_dist, follow_symlinks=True)
|
||||||
print(f"Copied {yazi_template} to {yazi_dist}")
|
print(f"Copied {yazi_template} to {yazi_dist}")
|
||||||
|
|
||||||
|
|
||||||
def change_wlogout(flavor):
|
def _change_wlogout(palette: dict[str, str], flavor: str):
|
||||||
wlogout_template = Path.home().joinpath('.config', 'wlogout', 'style.css.template')
|
wlogout_template = Path.home().joinpath('.config', 'wlogout', 'style.css.template')
|
||||||
wlogout_dist = copy_template(wlogout_template, Path.home().joinpath('.config', 'wlogout'))
|
wlogout_dist = copy_template(wlogout_template, Path.home().joinpath('.config', 'wlogout'))
|
||||||
apply_flavor(wlogout_dist, flavor)
|
replace_placeholders(wlogout_dist, palette, flavor)
|
||||||
|
|
||||||
for icon_template in Path.home().joinpath('.config', 'wlogout', 'icons').glob('*.svg.template'):
|
for icon_template in Path.home().joinpath('.config', 'wlogout', 'icons').glob('*.svg.template'):
|
||||||
icon_dist = copy_template(icon_template, Path.home().joinpath('.config', 'wlogout', 'icons'))
|
icon_dist = copy_template(icon_template, Path.home().joinpath('.config', 'wlogout', 'icons'))
|
||||||
apply_flavor(icon_dist, flavor)
|
replace_placeholders(icon_dist, palette, flavor)
|
||||||
|
|
||||||
|
|
||||||
def change_fuzzel(flavor):
|
def _change_fuzzel(palette: dict[str, str], flavor: str):
|
||||||
fuzzel_template = Path.home().joinpath('.config', 'fuzzel', 'fuzzel.ini.template')
|
fuzzel_template = Path.home().joinpath('.config', 'fuzzel', 'fuzzel.ini.template')
|
||||||
fuzzel_dist = copy_template(fuzzel_template, Path.home().joinpath('.config', 'fuzzel'))
|
fuzzel_dist = copy_template(fuzzel_template, Path.home().joinpath('.config', 'fuzzel'))
|
||||||
apply_flavor(fuzzel_dist, flavor)
|
replace_placeholders(fuzzel_dist, palette, flavor)
|
||||||
|
|
||||||
|
|
||||||
def match_color(color: str) -> str:
|
apply_theme_funcs: dict[str, Callable[[dict[str, str], str], None]] = {
|
||||||
""" Matches a given color to the closest color in the palette."""
|
'kvantum': _change_kvantum,
|
||||||
|
'nwg-look': _change_nwglook,
|
||||||
|
'eww': _change_eww,
|
||||||
|
'hypr': _change_hypr,
|
||||||
|
'rofi': _change_rofi,
|
||||||
|
'waybar': _change_waybar,
|
||||||
|
'oh-myposh': _change_ohmyposh,
|
||||||
|
'fastfetch': _change_fastfetch,
|
||||||
|
'mako': _change_mako,
|
||||||
|
'yazi': _change_yazi,
|
||||||
|
'wlogout': _change_wlogout,
|
||||||
|
'fuzzel': _change_fuzzel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def extract_color(image_path: str) -> str:
|
||||||
|
from colorthief import ColorThief
|
||||||
|
return "#{:02x}{:02x}{:02x}".format(*ColorThief(image_path).get_color(quality=10))
|
||||||
|
|
||||||
|
|
||||||
|
def match_color(color: str, palette: dict[str, str]) -> str:
|
||||||
|
""" Matches a given color (rrggbb hex) to the closest color in the palette."""
|
||||||
# HUE distance of the given and returned color must no<t exceed this value
|
# HUE distance of the given and returned color must no<t exceed this value
|
||||||
HUE_THRESHOLD = 60.0 # degrees
|
HUE_THRESHOLD = 60.0 # degrees
|
||||||
|
|
||||||
if not color.startswith('#'):
|
color = color.lower().strip().removeprefix('#')
|
||||||
color = f'#{color}'
|
|
||||||
color = color.lstrip('#')
|
|
||||||
|
|
||||||
def hex2rgb(hex_color: str) -> tuple[int, int, int]:
|
def hex2rgb(hex_color: str) -> tuple[int, int, int]:
|
||||||
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4))
|
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) # type: ignore
|
||||||
|
|
||||||
|
# weigh by CCIR 601 luminosity
|
||||||
|
fr, fg, fb = 0.299 / 255 / 255, 0.587 / 255 / 255, 0.114 / 255 / 255
|
||||||
|
lfr, lfg, lfb = 0.299 / 255, 0.587 / 255, 0.114 / 255
|
||||||
|
|
||||||
def color_distance(c1: str, c2: str) -> float:
|
def color_distance(c1: str, c2: str) -> float:
|
||||||
r1, g1, b1 = hex2rgb(c1)
|
r1, g1, b1 = hex2rgb(c1)
|
||||||
r2, g2, b2 = hex2rgb(c2)
|
r2, g2, b2 = hex2rgb(c2)
|
||||||
return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2
|
diff_l = (lfr * (r1 - r2) + lfg * (g1 - g2) + lfb * (b1 - b2))
|
||||||
|
diff_r = fr * (r1 - r2) ** 2
|
||||||
def rgb2hue(r, g, b) -> float:
|
diff_g = fg * (g1 - g2) ** 2
|
||||||
r, g, b = r / 255.0, g / 255.0, b / 255.0
|
diff_b = fb * (b1 - b2) ** 2
|
||||||
mx = max(r, g, b)
|
return (diff_r + diff_g + diff_b) * 0.75 + diff_l ** 2
|
||||||
mn = min(r, g, b)
|
|
||||||
diff = mx - mn
|
|
||||||
|
|
||||||
if diff == 0:
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
if mx == r:
|
|
||||||
hue = (g - b) / diff + (6 if g < b else 0)
|
|
||||||
elif mx == g:
|
|
||||||
hue = (b - r) / diff + 2
|
|
||||||
else:
|
|
||||||
hue = (r - g) / diff + 4
|
|
||||||
|
|
||||||
return hue * 60
|
|
||||||
|
|
||||||
def color_distance_hue(c1: str, c2: str) -> float:
|
def color_distance_hue(c1: str, c2: str) -> float:
|
||||||
|
def rgb2hue(r, g, b) -> float:
|
||||||
|
r, g, b = r / 255.0, g / 255.0, b / 255.0
|
||||||
|
mx = max(r, g, b)
|
||||||
|
mn = min(r, g, b)
|
||||||
|
diff = mx - mn
|
||||||
|
|
||||||
|
if diff == 0:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
if mx == r:
|
||||||
|
hue = (g - b) / diff + (6 if g < b else 0)
|
||||||
|
elif mx == g:
|
||||||
|
hue = (b - r) / diff + 2
|
||||||
|
else:
|
||||||
|
hue = (r - g) / diff + 4
|
||||||
|
|
||||||
|
return hue * 60
|
||||||
r1, g1, b1 = hex2rgb(c1)
|
r1, g1, b1 = hex2rgb(c1)
|
||||||
r2, g2, b2 = hex2rgb(c2)
|
r2, g2, b2 = hex2rgb(c2)
|
||||||
return abs(rgb2hue(r1, g1, b1) - rgb2hue(r2, g2, b2))
|
return abs(rgb2hue(r1, g1, b1) - rgb2hue(r2, g2, b2))
|
||||||
|
|
||||||
closest_color = min(CATPPUCIN_MOCHA_PALETTE.keys(), key=lambda k: color_distance(color, CATPPUCIN_MOCHA_PALETTE[k]))
|
closest_color = min(palette.keys(), key=lambda k: color_distance(color, palette[k]))
|
||||||
print(f"Matched color {color} to {closest_color}")
|
print(f"Matched color {color} to {closest_color}")
|
||||||
|
|
||||||
# if the hue distance is too large, rematch
|
# if the hue distance is too large, rematch
|
||||||
if abs(rgb2hue(*hex2rgb(color)) - rgb2hue(*hex2rgb(CATPPUCIN_MOCHA_PALETTE[closest_color]))) > HUE_THRESHOLD:
|
if color_distance_hue(color, palette[closest_color]) > HUE_THRESHOLD:
|
||||||
print(f"Color {color} is too far from {closest_color}, rematching'")
|
print(f"Color {color} is too far from {closest_color}, rematching'")
|
||||||
else:
|
else:
|
||||||
return closest_color
|
return closest_color
|
||||||
|
|
||||||
closest_color = min(CATPPUCIN_MOCHA_PALETTE.keys(), key=lambda k: color_distance_hue(color, CATPPUCIN_MOCHA_PALETTE[k]))
|
closest_color = min(palette.keys(), key=lambda k: color_distance_hue(color, palette[k]))
|
||||||
print(f"Rematched color {color} to {closest_color}")
|
print(f"Rematched color {color} to {closest_color}")
|
||||||
|
|
||||||
return closest_color
|
return closest_color
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
arguments = sys.argv[1:]
|
parser = argparse.ArgumentParser(description="Change color theme for various applications.")
|
||||||
if len(arguments) < 1 or arguments[0] in ('-h', '--help'):
|
parser.add_argument('-i', '--image', type=str, help="Path to the image")
|
||||||
print("Usage: change-colortheme.py <flavor|#rrggbb> [<app1> <app2> ...]")
|
parser.add_argument('-f', '--flavor', type=str, help="Flavor to apply")
|
||||||
sys.exit(1)
|
parser.add_argument('-c', '--color', type=str, help="Color to match from the palette")
|
||||||
|
parser.add_argument('arguments', nargs='*', help="List of applications to change the color theme of")
|
||||||
|
|
||||||
flavor = arguments[0] if not arguments[0].startswith('#') else match_color(arguments[0])
|
arguments = parser.parse_args()
|
||||||
app = arguments[1] if len(arguments) > 1 else None
|
|
||||||
|
|
||||||
if flavor not in CATPPUCIN_MOCHA_PALETTE:
|
# for future use, probably
|
||||||
print(f"Unknown flavor: {flavor}. Available flavors: {', '.join(CATPPUCIN_MOCHA_PALETTE.keys())}")
|
def parse_palette_name() -> str:
|
||||||
sys.exit(1)
|
return "catppuccin-mocha"
|
||||||
|
|
||||||
if app:
|
def parse_flavor(palette: dict[str, str]) -> str:
|
||||||
function_name = f"change_{app}"
|
if arguments.flavor:
|
||||||
if function_name in globals():
|
if arguments.flavor not in palette:
|
||||||
func = globals()[function_name]
|
print(f"Unknown flavor: {arguments.flavor}. Available flavors: {', '.join(palette.keys())}")
|
||||||
try:
|
sys.exit(1)
|
||||||
print(f"Changing color theme for {app} with flavor {flavor}...")
|
flavor = arguments.flavor
|
||||||
func(flavor)
|
elif arguments.color:
|
||||||
print("Success!")
|
flavor = match_color(arguments.color, palette)
|
||||||
except Exception as e:
|
print(f"Matched color: {flavor}")
|
||||||
print(f"Error while tweaking {app}: {e}")
|
elif arguments.image:
|
||||||
|
if not Path(arguments.image).exists():
|
||||||
|
print(f"Image file {arguments.image} does not exist.")
|
||||||
|
sys.exit(1)
|
||||||
|
color = extract_color(arguments.image)
|
||||||
|
print(f"Extracted color {color} from image {arguments.image}")
|
||||||
|
flavor = match_color(color, palette)
|
||||||
|
print(f"Extracted color: {flavor}")
|
||||||
else:
|
else:
|
||||||
print(f"Unknown app: {app}")
|
import random
|
||||||
else:
|
flavor = random.choice(list(palette.keys()))
|
||||||
for name, func in globals().items():
|
return flavor
|
||||||
if name.startswith('change_') and callable(func):
|
|
||||||
purename = name.removeprefix('change_')
|
|
||||||
try:
|
|
||||||
print(f"Changing color theme for {purename} with flavor {flavor}...")
|
|
||||||
func(flavor)
|
|
||||||
print("Success!")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error while tweaking {purename}: {e}")
|
|
||||||
|
|
||||||
os.system(f'notify-send "Color theme changed" "Catppuccin Mocha - {flavor}"')
|
def parse_apps() -> list[str]:
|
||||||
|
if not arguments.arguments:
|
||||||
|
return list(apply_theme_funcs.keys())
|
||||||
|
apps = []
|
||||||
|
for arg in arguments.arguments:
|
||||||
|
if arg not in apply_theme_funcs:
|
||||||
|
print(f"Unknown app: {arg}. Available apps: {', '.join(apply_theme_funcs.keys())}")
|
||||||
|
sys.exit(1)
|
||||||
|
apps.append(arg)
|
||||||
|
return apps
|
||||||
|
|
||||||
# def is_interactive_shell() -> bool:
|
palette_name = parse_palette_name()
|
||||||
# return sys.stdin.isatty() and sys.stdout.isatty()
|
palette = PALETTES[palette_name]
|
||||||
|
flavor = parse_flavor(palette)
|
||||||
|
apps = parse_apps()
|
||||||
|
|
||||||
# def is_fish() -> bool:
|
for app in apps:
|
||||||
# import psutil
|
func = apply_theme_funcs[app]
|
||||||
# parent = psutil.Process().parent()
|
try:
|
||||||
# return parent is not None and 'fish' in parent.name().lower()
|
print(f"Changing color theme of {app} to flavor {flavor}...")
|
||||||
|
func(palette, flavor)
|
||||||
|
print("Success!\n")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error while tweaking {app}: {e}")
|
||||||
|
|
||||||
# if not app or app == 'fastfetch' \
|
os.system(f'notify-send "Color theme changed" "Palette: {palette_name}\nFlavor: {flavor}"')
|
||||||
# and is_interactive_shell() \
|
|
||||||
# and is_fish():
|
|
||||||
# os.system('fish')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
###
|
|
||||||
# @Author: Uyanide pywang0608@foxmail.com
|
|
||||||
# @Date: 2025-06-14 20:23:25
|
|
||||||
# @LastEditTime: 2025-08-03 00:33:45
|
|
||||||
# @Description: Change the desktop wallpaper and update colortheme
|
|
||||||
###
|
|
||||||
#!/bin/fish
|
#!/bin/fish
|
||||||
|
|
||||||
# if the path is given as an argument, use that
|
# if the path is given as an argument, use that
|
||||||
@@ -21,7 +15,7 @@ if not test -f "$image"
|
|||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
if string match -q "* *" "$image"
|
if string match -q "* *" "$image"
|
||||||
notify-send "Error" "Selected file path contains white spaces, please select a file without white spaces."
|
notify-send "Error" "The path of selected file contains white spaces, please select a file without white spaces."
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -31,7 +25,5 @@ echo "wallpaper = , $image" >> ~/.config/hypr/hyprpaper.conf
|
|||||||
|
|
||||||
notify-send "Wallpaper Changed" "$image"
|
notify-send "Wallpaper Changed" "$image"
|
||||||
|
|
||||||
change-colortheme.py "#$(
|
notify-send "Extracting colors from wallpaper" "This may take a few seconds..."
|
||||||
notify-send "Extracting color from wallpaper" "This may take a few seconds..."
|
change-colortheme.py -i "$image"
|
||||||
extract-color.py "$image"
|
|
||||||
)"
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/env python3
|
|
||||||
import sys
|
|
||||||
from colorthief import ColorThief
|
|
||||||
|
|
||||||
|
|
||||||
def extract_colors(image_path, palette_size=0):
|
|
||||||
"""
|
|
||||||
Extracts the dominant color and a palette of colors from an image.
|
|
||||||
|
|
||||||
:param image_path: Path to the image file.
|
|
||||||
:param palette_size: Number of colors to extract (default is 5).
|
|
||||||
:return: A tuple containing the dominant color and a list of palette colors.
|
|
||||||
"""
|
|
||||||
if palette_size != 0 and palette_size < 2:
|
|
||||||
raise ValueError("palette_size must not be fewer than 2.")
|
|
||||||
color_thief = ColorThief(image_path)
|
|
||||||
dominant_color = color_thief.get_color(quality=1)
|
|
||||||
palette = color_thief.get_palette(color_count=palette_size) if palette_size > 0 else []
|
|
||||||
return dominant_color, palette
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if len(sys.argv) != 2:
|
|
||||||
print("Usage: extract-color.py <image_path>")
|
|
||||||
sys.exit(1)
|
|
||||||
print("{:02x}{:02x}{:02x}".format(*extract_colors(sys.argv[1])[0]), end=' ')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"max-length": 2
|
"max-length": 2
|
||||||
},
|
},
|
||||||
"custom/rofi": {
|
"custom/rofi": {
|
||||||
"format": "",
|
"format": "",
|
||||||
"tooltip": false,
|
"tooltip": false,
|
||||||
// "on-click-right": "fuzzel -l 0 -p '>> ' | xargs -r sh -c",
|
// "on-click-right": "fuzzel -l 0 -p '>> ' | xargs -r sh -c",
|
||||||
// "on-click": "fuzzel",
|
// "on-click": "fuzzel",
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"network#speed": {
|
"network#speed": {
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"format": "{ifname}",
|
"format": "{ifname}",
|
||||||
"format-wifi": " {bandwidthDownBytes} {bandwidthUpBytes} ",
|
"format-wifi": " {bandwidthDownBytes} {bandwidthUpBytes} ",
|
||||||
"format-ethernet": " {bandwidthDownBytes} {bandwidthUpBytes} ",
|
"format-ethernet": " {bandwidthDownBytes} {bandwidthUpBytes} ",
|
||||||
"format-disconnected": "",
|
"format-disconnected": "",
|
||||||
"tooltip-format": "{ipaddr}",
|
"tooltip-format": "{ipaddr}",
|
||||||
"format-linked": " {ifname} (No IP)",
|
"format-linked": " {ifname} (No IP)",
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"critical-threshold": 80,
|
"critical-threshold": 80,
|
||||||
// "format-critical": " {temperatureC}°C",
|
// "format-critical": " {temperatureC}°C",
|
||||||
"format-critical": " {temperatureC}°C",
|
"format-critical": " {temperatureC}°C",
|
||||||
"format": "{icon} {temperatureC}°C",
|
"format": "{icon} {temperatureC}°C",
|
||||||
"format-icons": ["", "", ""],
|
"format-icons": ["", "", ""],
|
||||||
"max-length": 6,
|
"max-length": 6,
|
||||||
"min-length": 6
|
"min-length": 6
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
"memory": {
|
"memory": {
|
||||||
"interval": 11,
|
"interval": 11,
|
||||||
// "format": " {used:0.2f} / {total:0.0f} GB",
|
// "format": " {used:0.2f} / {total:0.0f} GB",
|
||||||
"format": " {percentage}%",
|
"format": " {percentage}%",
|
||||||
"on-click": "killall btop || ghostty -e btop",
|
"on-click": "killall btop || ghostty -e btop",
|
||||||
"max-length": 6,
|
"max-length": 6,
|
||||||
"min-length": 6
|
"min-length": 6
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"cpu": {
|
"cpu": {
|
||||||
"interval": 3,
|
"interval": 3,
|
||||||
//"format": " {}%", // Icon: microchip
|
//"format": " {}%", // Icon: microchip
|
||||||
"format": " {usage}%",
|
"format": " {usage}%",
|
||||||
"max-length": 6,
|
"max-length": 6,
|
||||||
"min-length": 6,
|
"min-length": 6,
|
||||||
"on-click": "killall btop || ghostty -e btop"
|
"on-click": "killall btop || ghostty -e btop"
|
||||||
@@ -130,9 +130,9 @@
|
|||||||
"warning": 30,
|
"warning": 30,
|
||||||
"critical": 15
|
"critical": 15
|
||||||
},
|
},
|
||||||
"format": "{icon} {capacity}%",
|
"format": "{icon} {capacity}%",
|
||||||
"format-charging": " {capacity}%",
|
"format-charging": " {capacity}%",
|
||||||
"format-plugged": " {capacity}%",
|
"format-plugged": " {capacity}%",
|
||||||
"format-icons": ["", "", "", "", ""],
|
"format-icons": ["", "", "", "", ""],
|
||||||
"max-length": 6,
|
"max-length": 6,
|
||||||
"min-length": 6
|
"min-length": 6
|
||||||
@@ -216,19 +216,16 @@
|
|||||||
"on-click": "~/.scripts/workspace-new.sh"
|
"on-click": "~/.scripts/workspace-new.sh"
|
||||||
},
|
},
|
||||||
"hyprland/window": {
|
"hyprland/window": {
|
||||||
|
"format": "{class}",
|
||||||
"max-length": 100,
|
"max-length": 100,
|
||||||
"separate-outputs": true,
|
"separate-outputs": true,
|
||||||
"icon": true,
|
"icon": true,
|
||||||
"icon-size": 15
|
"icon-size": 14
|
||||||
},
|
},
|
||||||
"custom/mediaplayer": {
|
"custom/mediaplayer": {
|
||||||
"format": "{text}",
|
"format": "{text}",
|
||||||
"return-type": "json",
|
"return-type": "json",
|
||||||
"max-length": 100,
|
"max-length": 100,
|
||||||
"format-icons": {
|
|
||||||
"spotify": "",
|
|
||||||
"default": ""
|
|
||||||
},
|
|
||||||
"escape": true,
|
"escape": true,
|
||||||
"exec": "$HOME/.config/waybar/modules/mediaplayer.py 2> /dev/null",
|
"exec": "$HOME/.config/waybar/modules/mediaplayer.py 2> /dev/null",
|
||||||
"on-click": "playerctl play-pause",
|
"on-click": "playerctl play-pause",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
@import 'mocha.css';
|
@import 'mocha.css';
|
||||||
|
|
||||||
@define-color flavor #f5c2e7;
|
@define-color flavor #f5c2e7;
|
||||||
|
/* @define-color archlinux #1793d1; */
|
||||||
|
@define-color archlinux @sapphire;
|
||||||
|
|
||||||
/* Font(s) */
|
/* Font(s) */
|
||||||
* {
|
* {
|
||||||
@@ -153,11 +155,12 @@ window#waybar.empty #window{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#custom-rofi {
|
#custom-rofi {
|
||||||
border: 3px solid @teal;
|
color: @archlinux;
|
||||||
|
border: 3px solid @archlinux;
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-rofi:hover {
|
#custom-rofi:hover {
|
||||||
background-color: alpha(@teal, 0.3);
|
background-color: alpha(@archlinux, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-caffeine {
|
#custom-caffeine {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
@import 'mocha.css';
|
@import 'mocha.css';
|
||||||
|
|
||||||
@define-color flavor #<FLAVOR_HEX>;
|
@define-color flavor #<FLAVOR_HEX>;
|
||||||
|
/* @define-color archlinux #1793d1; */
|
||||||
|
@define-color archlinux @sapphire;
|
||||||
|
|
||||||
/* Font(s) */
|
/* Font(s) */
|
||||||
* {
|
* {
|
||||||
@@ -153,11 +155,12 @@ window#waybar.empty #window{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#custom-rofi {
|
#custom-rofi {
|
||||||
border: 3px solid @teal;
|
color: @archlinux;
|
||||||
|
border: 3px solid @archlinux;
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-rofi:hover {
|
#custom-rofi:hover {
|
||||||
background-color: alpha(@teal, 0.3);
|
background-color: alpha(@archlinux, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#custom-caffeine {
|
#custom-caffeine {
|
||||||
|
|||||||
Reference in New Issue
Block a user