feat: implement generic get_app_config_dirs helper to dynamically discover and sync themes for all Flatpak applications

This commit is contained in:
Sho 2026-08-01 23:43:56 +09:00
parent d7b1a6a4e7
commit 19bb1399e8

View File

@ -1,6 +1,55 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os, sys, argparse, re import os, sys, argparse, re
def get_app_config_dirs(app_names):
"""
Dynamically discover all config and data directories for any native or Flatpak application.
Checks ~/.config/, ~/.local/share/, ~/.var/app/* (Flatpak sandboxes), and system paths.
"""
if isinstance(app_names, str):
app_names = [app_names]
dirs = set()
home = os.path.expanduser('~')
for name in app_names:
c1 = os.path.join(home, '.config', name)
c2 = os.path.join(home, '.local', 'share', name)
if os.path.exists(c1):
dirs.add(c1)
if os.path.exists(c2):
dirs.add(c2)
var_app = os.path.join(home, '.var', 'app')
if os.path.exists(var_app):
try:
for entry in os.scandir(var_app):
if not entry.is_dir():
continue
sub_locations = [
os.path.join(entry.path, 'config'),
os.path.join(entry.path, 'data'),
os.path.join(entry.path, '.config'),
os.path.join(entry.path, '.local', 'share')
]
for sub_loc in sub_locations:
if not os.path.exists(sub_loc):
continue
for name in app_names:
target = os.path.join(sub_loc, name)
if os.path.exists(target):
dirs.add(target)
try:
for item in os.scandir(sub_loc):
if any(n.lower() in item.name.lower() for n in app_names):
dirs.add(item.path)
except Exception:
pass
except Exception:
pass
return list(dirs)
def sync_gtk(bg, surface, current_line, fg, accent, is_dark): def sync_gtk(bg, surface, current_line, fg, accent, is_dark):
css_content = f"""/* Auto-generated by Quickshell Theme Engine */ css_content = f"""/* Auto-generated by Quickshell Theme Engine */
@define-color window_bg_color {bg}; @define-color window_bg_color {bg};
@ -705,12 +754,15 @@ def sync_feishin(bg, surface, current_line, fg, accent, sub_accent, is_dark, var
import json, glob import json, glob
active_slug = slugify(variant_name) active_slug = slugify(variant_name)
feishin_dirs = [ feishin_dirs = get_app_config_dirs(['feishin', 'Feishin'])
for fb in [
os.path.expanduser('~/.config/feishin'), os.path.expanduser('~/.config/feishin'),
os.path.expanduser('~/.var/app/io.github.jeffvli.feishin/config/feishin'), os.path.expanduser('~/.var/app/io.github.jeffvli.feishin/config/feishin'),
os.path.expanduser('~/.var/app/org.jeffvli.feishin/config/feishin'), os.path.expanduser('~/.var/app/org.jeffvli.feishin/config/feishin'),
os.path.expanduser('~/.var/app/feishin/config/feishin') os.path.expanduser('~/.var/app/feishin/config/feishin')
] ]:
if fb not in feishin_dirs:
feishin_dirs.append(fb)
for base_dir in feishin_dirs: for base_dir in feishin_dirs:
try: try:
@ -733,15 +785,29 @@ def sync_feishin(bg, surface, current_line, fg, accent, sub_accent, is_dark, var
v_slug = slugify(v["name"]) v_slug = slugify(v["name"])
v_json = make_feishin_json(v["bg"], v["surface"], v["currentLine"], v["fg"], v["accent"], v["isDark"], v["name"], v_slug) v_json = make_feishin_json(v["bg"], v["surface"], v["currentLine"], v["fg"], v["accent"], v["isDark"], v["name"], v_slug)
v_path = os.path.join(themes_dir, f"{v_slug}.json") v_path = os.path.join(themes_dir, f"{v_slug}.json")
with open(v_path, 'w') as f: with open(v_path, 'w', encoding='utf-8') as f:
json.dump(v_json, f, indent=2) json.dump(v_json, f, indent=2)
# 3. Write active variant JSON with runtime parameters # 3. Write active variant JSON with runtime parameters + quickshell.json
active_json = make_feishin_json(bg, surface, current_line, fg, accent, is_dark, variant_name, active_slug) active_json = make_feishin_json(bg, surface, current_line, fg, accent, is_dark, variant_name, active_slug)
active_path = os.path.join(themes_dir, f"{active_slug}.json") active_path = os.path.join(themes_dir, f"{active_slug}.json")
with open(active_path, 'w') as f: with open(active_path, 'w', encoding='utf-8') as f:
json.dump(active_json, f, indent=2) json.dump(active_json, f, indent=2)
with open(os.path.join(themes_dir, "quickshell.json"), 'w', encoding='utf-8') as f:
json.dump(active_json, f, indent=2)
# 4. Auto-update preferences.json in Feishin config directory if present
pref_file = os.path.join(base_dir, 'preferences.json')
if os.path.exists(pref_file):
try:
with open(pref_file, 'r', encoding='utf-8') as f:
pref_data = json.load(f)
pref_data["theme"] = active_slug
with open(pref_file, 'w', encoding='utf-8') as f:
json.dump(pref_data, f, indent=2)
except Exception:
pass
except Exception: except Exception:
pass pass