diff --git a/settings/theming.nix b/settings/theming.nix index f2d782e..a1566de 100644 --- a/settings/theming.nix +++ b/settings/theming.nix @@ -536,24 +536,38 @@ let reply=$(${pkgs.hyprland}/bin/hyprctl eval "$(cat "$theme/hypr.lua")" 2>&1) [ "$reply" = "ok" ] || echo "hyprctl eval -> $reply" - # Ghostty holds its config in one process (gtk-single-instance), so a new - # window inherits whatever the daemon parsed at startup — reopening a - # terminal is NOT enough to pick up a new theme. + # Ghostty holds its config in one process, so a new window inherits + # whatever that process parsed at startup — reopening a terminal is NOT + # enough to pick up a new theme. # - # It is a GTK application, so it publishes its actions on the session bus; - # `reload-config` is the same action the reload_config keybind fires. Going - # through D-Bus works with no window open, needs no window focused, and - # doesn't depend on synthesising a keypress into the right surface. - if ! ${pkgs.glib.bin}/bin/gdbus call --session \ - --dest com.mitchellh.ghostty \ - --object-path /com/mitchellh/ghostty \ + # There are TWO processes to tell, not one. gtk-single-instance funnels + # every plain `ghostty` into the com.mitchellh.ghostty instance, but the + # scratchpad launches with --class=dev.fred.scratchpad, and ghostty's + # --class IS the GTK application id — which is exactly how it forces a + # separate instance (see settings/hyprland.nix). A separate instance + # means its own bus name and its own object path, so a reload aimed at + # com.mitchellh.ghostty never reaches it and the scratchpad sat on the + # old palette until it was killed. + # + # Both are GTK applications publishing their actions on the session bus; + # `reload-config` is the same action the reload_config keybind fires. + # Going through D-Bus works with no window open, needs no window focused, + # and doesn't depend on synthesising a keypress into the right surface. + ghostty_reload() { + ${pkgs.glib.bin}/bin/gdbus call --session \ + --dest "$1" --object-path "$2" \ --method org.gtk.Actions.Activate \ - reload-config '[]' '{}' >/dev/null 2>&1; then + reload-config '[]' '{}' >/dev/null 2>&1 + } + + # Absent is not a failure: the scratchpad only exists once SUPER+Return + # has been pressed this session. + ghostty_reload dev.fred.scratchpad /dev/fred/scratchpad || true + + if ! ghostty_reload com.mitchellh.ghostty /com/mitchellh/ghostty; then # No instance on the bus, or the action is gone. Restarting the daemon # fixes it but takes every open terminal with it, so that is only on the - # table when there is nothing to lose. The class test has to cover the - # --class override from settings/hyprland.nix (dev.fred.scratchpad) — - # that window is the same process. + # table when there is nothing to lose. The class test covers both ids. if ${pkgs.hyprland}/bin/hyprctl -j clients 2>/dev/null \ | ${pkgs.jq}/bin/jq -e 'any(.[].class; test("ghostty|^dev\\.fred\\."))' >/dev/null 2>&1; then echo "ghostty reload-config failed; open terminals keep the old theme"