diff --git a/quickshell/services/python/theme_sync.py b/quickshell/services/python/theme_sync.py index b77a279..c12c6de 100644 --- a/quickshell/services/python/theme_sync.py +++ b/quickshell/services/python/theme_sync.py @@ -50,6 +50,67 @@ def get_app_config_dirs(app_names): return list(dirs) +def restart_app_if_running(name, search_patterns, launch_commands): + """ + Gracefully restarts a native or Flatpak application if it is currently running. + """ + import subprocess, time + + is_running = False + for pat in search_patterns: + res = subprocess.run(["pgrep", "-i", "-f", pat], capture_output=True, text=True) + if res.returncode == 0: + is_running = True + break + + if not is_running: + return + + # Gracefully terminate running instances + for pat in search_patterns: + subprocess.run(["pkill", "-15", "-i", "-f", pat], capture_output=True) + + # Wait for process exit & lock release buffer + for _ in range(30): + still_running = False + for pat in search_patterns: + check = subprocess.run(["pgrep", "-i", "-f", pat], capture_output=True, text=True) + if check.returncode == 0: + still_running = True + break + if not still_running: + time.sleep(0.5) + break + time.sleep(0.1) + + # Launch using first available working launch command (Flatpak -> Desktop launcher -> Native binary) + for cmd in launch_commands: + try: + if cmd.startswith("flatpak run"): + app_id = cmd.split()[-1] + check_fp = subprocess.run(["flatpak", "info", app_id], capture_output=True, text=True) + if check_fp.returncode == 0: + subprocess.Popen(cmd, shell=True, start_new_session=True) + return + elif cmd.startswith("gtk-launch"): + app_id = cmd.split()[-1] + res_gtk = subprocess.run(["gtk-launch", app_id], capture_output=True) + if res_gtk.returncode == 0: + return + else: + bin_name = cmd.split()[0] + res_bin = subprocess.run(f"command -v {bin_name}", capture_output=True, shell=True) + if res_bin.returncode == 0: + subprocess.Popen(cmd, shell=True, start_new_session=True) + return + except Exception: + pass + + # Generic shell fallback launch + if launch_commands: + raw_cmd = " || ".join(launch_commands) + subprocess.Popen(f"sh -c '{raw_cmd} &'", shell=True, start_new_session=True) + def sync_gtk(bg, surface, current_line, fg, accent, is_dark): css_content = f"""/* Auto-generated by Quickshell Theme Engine */ @define-color window_bg_color {bg}; @@ -651,18 +712,20 @@ tab[selected="true"] {{ except Exception: pass - # Graceful SIGTERM restart with profile lock release buffer - res = subprocess.run(["pgrep", "-f", "zen-browser"], capture_output=True, text=True) - if res.returncode == 0: - subprocess.run(["pkill", "-15", "-f", "zen-browser"]) - import time - for _ in range(30): - check = subprocess.run(["pgrep", "-f", "zen-browser"], capture_output=True, text=True) - if check.returncode != 0: - time.sleep(0.6) # Safety buffer for lock release - break - time.sleep(0.1) - subprocess.Popen(["zen-browser"], start_new_session=True) + restart_app_if_running( + "zen", + ["zen-browser", "zen-bin", "zen_browser", "app.zen_browser.zen", "io.github.zen_browser.zen"], + [ + "flatpak run app.zen_browser.zen", + "flatpak run io.github.zen_browser.zen", + "gtk-launch app.zen_browser.zen", + "gtk-launch io.github.zen_browser.zen", + "gtk-launch zen-browser", + "zen-browser", + "zen-bin", + "zen" + ] + ) def hex_to_rgb(hex_str): try: @@ -811,6 +874,18 @@ def sync_feishin(bg, surface, current_line, fg, accent, sub_accent, is_dark, var except Exception: pass + restart_app_if_running( + "feishin", + ["feishin", "io.github.jeffvli.feishin", "org.jeffvli.feishin"], + [ + "flatpak run io.github.jeffvli.feishin", + "flatpak run org.jeffvli.feishin", + "gtk-launch io.github.jeffvli.feishin", + "gtk-launch feishin", + "feishin" + ] + ) + def sync_starship(bg, surface, current_line, fg, accent, sub_accent, is_dark): starship_dir = os.path.expanduser('~/.config') os.makedirs(starship_dir, exist_ok=True)