diff --git a/modules/nix-darwin/yabai/default.nix b/modules/nix-darwin/yabai/default.nix index 4671fb8..c597cdd 100644 --- a/modules/nix-darwin/yabai/default.nix +++ b/modules/nix-darwin/yabai/default.nix @@ -36,24 +36,46 @@ in ${builtins.readFile ./yabairc} # Load JankyBorders - ${borders}/bin/borders active_color=0xffe1e3e4 inactive_color=0xff494d64 width=5.0 & + ${borders}/bin/borders active_color=0xffe1e3e4 inactive_color=0xff494d64 style=squared width=5.0 & ''; }; skhd = { enable = true; package = pkgs.skhd; - skhdConfig = (builtins.readFile ./skhdrc); + skhdConfig = builtins.readFile ./skhdrc; }; - sketchybar = { - enable = true; + # sketchybar = { + # enable = true; + # package = pkgs.sketchybar; + # extraPackages = with pkgs; [ + # jq + # ]; + # config = import (lib.getExe (pkgs.callPackage ./sketchybar { })); + # }; + }; + + # TODO: make builtin module work with scripts + launchd.user.agents.sketchybar = let + cfg = rec { package = pkgs.sketchybar; extraPackages = with pkgs; [ jq ]; - config = import ./sketchybar pkgs; + configFile = lib.getExe (pkgs.callPackage ./sketchybar { sketchybar = package; }); }; + in { + path = [ cfg.package ] ++ cfg.extraPackages ++ [ config.environment.systemPath ]; + serviceConfig.ProgramArguments = + [ + "${lib.getExe cfg.package}" + ] ++ optionals (cfg.configFile != null) [ + "--config" + "${cfg.configFile}" + ]; + serviceConfig.KeepAlive = true; + serviceConfig.RunAtLoad = true; }; # For sketchybar diff --git a/modules/nix-darwin/yabai/sketchybar/config.clj b/modules/nix-darwin/yabai/sketchybar/config.clj new file mode 100644 index 0000000..c3e15a5 --- /dev/null +++ b/modules/nix-darwin/yabai/sketchybar/config.clj @@ -0,0 +1,210 @@ +#!/usr/bin/env bb + +(ns sketchybar-config + (:require [babashka.process :refer [shell]] + [babashka.cli :as cli] + [clojure.string :as str])) + +(def cli-options {:plugin-dir {} + :util-dir {} + :get-menu-bar-height {}}) + +(def args (cli/parse-opts *command-line-args* {:spec cli-options})) + +(def plugin-dir (:plugin-dir args)) +(def util-dir (:util-dir args)) +(def get-menu-bar-height-script (:get-menu-bar-height args)) + +(def env {"PLUGIN_DIR" plugin-dir + "UTIL_DIR" util-dir}) + +(defn transform-list [coll] + (loop [items coll + result []] + (cond + (empty? items) + result + + (and (keyword? (first items)) (nil? (second items))) + (recur (drop 2 items) result) + + (keyword? (first items)) + (recur (drop 2 items) + (conj result + (str (name (first items)) + "=" + (second items)))) + + :else + (recur (rest items) (conj result (first items)))))) + +(defn run [cmd] + (->> cmd + transform-list + (apply shell {:out :string :extra-env env}) + eval + :out + str/trim)) + +;; Function to get menu bar height +(defn get-menu-bar-height [] + (run [get-menu-bar-height-script])) + +;; Dynamic background color based on system appearance +(def background-color + (let [appearance (run ["defaults" "read" "-g" "AppleInterfaceStyle"])] + (if (= appearance "Dark") + "0x502a2d3d" + "0x50f5f0f5"))) + +;; Sketchybar command helpers +(defn sketchybar [& args] + (run (cons "sketchybar" args))) + +;; Set up the bar appearance +(defn setup-bar [] + (sketchybar + "--bar" + :height (get-menu-bar-height) + :blur_radius "25" + :position "top" + :sticky "on" + :margin "10" + :color "0x002a2d3d" + :notch_offset "5" + :corner_radius "12" + :border_color "0x80c4a7e7" + :border_width "0")) + +;;; Changing Defaults ;;; +;; We now change some default values that are applied to all further items +;; For a full list of all available item properties see: +;; https://felixkratz.github.io/SketchyBar/config/items +(defn set-defaults [] + (sketchybar + "--default" + :updates "when_shown" + :icon.font "SF Pro Rounded:Bold:14.0" + :icon.color "0xffc6ceef" + :label.font "SF Pro Rounded:Bold:14.0" + :label.color "0xffc6ceef" + :padding_left "3" + :padding_right "3" + :label.padding_left "4" + :label.padding_right "4" + :icon.padding_left "4" + :icon.padding_right "4")) + +;;; Adding Mission Control Space Indicators ;;; +;; Now we add some mission control spaces: +;; https://felixkratz.github.io/SketchyBar/config/components#space----associate-mission-control-spaces-with-an-item +;; to indicate active and available mission control spaces +(defn add-spaces [] + (let [space-icons ["1" "2" "3" "4" "5" "6" "7" "8" "9" "10"]] + (doseq [i (range (count space-icons))] + (let [space-id (inc i) + icon (nth space-icons i)] + (sketchybar + "--add" "space" (str "space." space-id) "left" + "--set" (str "space." space-id) + :associated_space space-id + :icon icon + :background.color "0x44ffffff" + :background.corner_radius "7" + :background.height "20" + :background.drawing "on" + :background.border_color "0x952a2d3d" + :background.border_width "1" + :label.drawing "off" + :script (str plugin-dir "/space.sh") + :click_script (str "yabai -m space --focus " space-id)))))) + +;;; Adding Left Items ;;; +;; We add some regular items to the left side of the bar +;; only the properties deviating from the current defaults need to be set +(defn add-front-app [] + (sketchybar + "--add" "item" "space_separator" "left" + "--set" "space_separator" + :icon "λ" + :icon.color "0xffff946f" + :padding_left "10" + :padding_right "10" + :label.drawing "off") + (sketchybar + "--add" "item" "front_app" "left" + "--set" "front_app" + :script (str plugin-dir "/front_app.sh") + :icon.drawing "off" + :background.color background-color + :background.corner_radius "7" + :blur_radius "30" + :background.border_color "0x80c4a7e7" + :background.border_width "1" + "--subscribe" "front_app" "front_app_switched")) + +;;; Adding Right Items ;;; +;; In the same way as the left items we can add items to the right side. +;; Additional position (e.g. center) are available, see: +;; https://felixkratz.github.io/SketchyBar/config/items#adding-items-to-sketchybar +;; +;; Some items refresh on a fixed cycle, e.g. the clock runs its script once +;; every 10s. Other items respond to events they subscribe to, e.g. the +;; volume.sh script is only executed once an actual change in system audio +;; volume is registered. More info about the event system can be found here: +;; https://felixkratz.github.io/SketchyBar/config/events +(defn add-right-items [] + (let [items [{:name "clock" + :icon "􀐬" + :script (str plugin-dir "/clock.sh") + :update-freq 10 + :subscribe []} + {:name "wifi" + :icon "􀙇" + :script (str plugin-dir "/wifi.sh")} + {:name "volume" + :script (str plugin-dir "/volume.sh")} + {:name "battery" + :script (str plugin-dir "/battery.sh") + :update_freq 120 + :subscribe ["battery" "system_woke" "power_source_change"]}]] + (doseq [{:keys [name icon script update-freq subscribe]} + items] + ;; NOTE: `apply` because of `subscribe` (a list) + (apply sketchybar + "--add" "item" name "right" + "--set" name + :script script + :icon icon + :update_freq (or update-freq 0) + :background.color background-color + :background.corner_radius "7" + :icon.padding_left "10" + :label.padding_right "10" + :blur_radius "30" + :background.border_color "0x80c4a7e7" + :background.border_width "1" + ;; FIXME: ugly + (if subscribe + (if (not= subscribe []) + (cons "--subscribe" subscribe) + []) + ["--subscribe" name (str name "_change")]))))) + + +;;; Finalizing Setup ;;; +;; The below command is only needed at the end of the initial configuration to +;; force all scripts to run the first time, it should never be run in an item script.) +(defn finalize [] + (sketchybar "--update")) + +;; Main function +(defn main [] + (setup-bar) + (set-defaults) + (add-spaces) + (add-front-app) + (add-right-items) + (finalize)) + +(main) diff --git a/modules/nix-darwin/yabai/sketchybar/default.nix b/modules/nix-darwin/yabai/sketchybar/default.nix index bd0132b..e685a7a 100755 --- a/modules/nix-darwin/yabai/sketchybar/default.nix +++ b/modules/nix-darwin/yabai/sketchybar/default.nix @@ -1,11 +1,10 @@ # TODO: AppleSelectedInputSourcesChangedNotification -# TODO: no `PLUGIN_DIR` and `UTIL_DIR`, directly reference scripts -{ lib, darwin, ... }: +{ lib, darwin, writeShellApplication, sketchybar, babashka, clj-kondo, ... }: let - plugin_dir = ./plugins; - util_dir = ./utils; - get_menu_bar_height = darwin.apple_sdk.stdenv.mkDerivation { + plugin-dir = ./plugins; + util-dir = ./utils; + get-menu-bar-height = darwin.apple_sdk.stdenv.mkDerivation { name = "get_menu_bar_height"; version = "0.0.1"; src = lib.cleanSource ./get_menu_bar_height; @@ -19,156 +18,28 @@ let mkdir -p $out/bin mv get_menu_bar_height $out/bin/get_menu_bar_height ''; + meta.mainProgram = "get_menu_bar_height"; }; + sketchybar-config-script = ./config.clj; in -'' - export PLUGIN_DIR="${plugin_dir}" - export UTIL_DIR="${util_dir}" +writeShellApplication { + name = "sketchybar-config"; + text = '' + export PLUGIN_DIR="${plugin-dir}" + export UTIL_DIR="${util-dir}" - ##### Bar Appearance ##### - BACKGROUND_COLOR="0x502a2d3d" - - appearance=''$''\(defaults read -g AppleInterfaceStyle''\) - - if [[ ''$''\{appearance''\} != 'Dark' ]]; then - BACKGROUND_COLOR="0x50f5f0f5" - fi - - height=''$''\(${get_menu_bar_height}/bin/get_menu_bar_height''\) - - sketchybar --bar height="32" \ - blur_radius="25" \ - position="top" \ - sticky="on" \ - margin="10" \ - color="0x002a2d3d" \ - notch_offset="5" \ - corner_radius="12" \ - border_color="0x80c4a7e7" \ - border_width="0" - - ##### Changing Defaults ##### - # We now change some default values that are applied to all further items - # For a full list of all available item properties see: - # https://felixkratz.github.io/SketchyBar/config/items - - sketchybar --default updates="when_shown" \ - icon.font="SF Pro Rounded:Bold:14.0" \ - icon.color="0xffc6ceef" \ - label.font="SF Pro Rounded:Bold:14.0" \ - label.color="0xffc6ceef" \ - padding_left="3" \ - padding_right="3" \ - label.padding_left="4" \ - label.padding_right="4" \ - icon.padding_left="4" \ - icon.padding_right="4" - - ##### Adding Mission Control Space Indicators ##### - # Now we add some mission control spaces: - # https://felixkratz.github.io/SketchyBar/config/components#space----associate-mission-control-spaces-with-an-item - # to indicate active and available mission control spaces - - SPACE_ICONS=("1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16") - - for i in "''$''\{!SPACE_ICONS[@]''\}"; do - sid=$(($i+1)) - sketchybar --add space space.''$''\{sid''\} left \ - --set space.''$''\{sid''\} associated_space="''$''\{sid''\}" \ - icon="''$''\{SPACE_ICONS[i]''\}" \ - background.color="0x44ffffff" \ - background.corner_radius="7" \ - background.height="20" \ - background.drawing="on" \ - background.border_color="0x952a2d3d" \ - background.border_width="1" \ - label.drawing="off" \ - script="''$''\{PLUGIN_DIR''\}/space.sh" \ - click_script="yabai -m space --focus ''$''\{sid''\}" - done - - ##### Adding Left Items ##### - # We add some regular items to the left side of the bar - # only the properties deviating from the current defaults need to be set - - sketchybar --add item space_separator left \ - --set space_separator icon="λ" \ - icon.color="0xffff946f" \ - padding_left="10" \ - padding_right="10" \ - label.drawing="off" \ - \ - --add item front_app left \ - --set front_app script="''$''\{PLUGIN_DIR''\}/front_app.sh" \ - icon.drawing="off" \ - background.color="''$''\{BACKGROUND_COLOR''\}" \ - background.corner_radius="7" \ - blur_radius="30" \ - background.border_color="0x80c4a7e7" \ - background.border_width="1" \ - --subscribe front_app front_app_switched - - ##### Adding Right Items ##### - # In the same way as the left items we can add items to the right side. - # Additional position (e.g. center) are available, see: - # https://felixkratz.github.io/SketchyBar/config/items#adding-items-to-sketchybar - - # Some items refresh on a fixed cycle, e.g. the clock runs its script once - # every 10s. Other items respond to events they subscribe to, e.g. the - # volume.sh script is only executed once an actual change in system audio - # volume is registered. More info about the event system can be found here: - # https://felixkratz.github.io/SketchyBar/config/events - - sketchybar --add item clock right i \ - --set clock update_freq="10" \ - icon="􀐬" \ - background.color="''$''\{BACKGROUND_COLOR''\}" \ - background.corner_radius="7" \ - icon.padding_left="10" \ - label.padding_right="10" \ - blur_radius="30" \ - background.border_color="0x80c4a7e7" \ - background.border_width="1" \ - script="''$''\{PLUGIN_DIR''\}/clock.sh" \ - \ - --add item wifi right \ - --set wifi script="''$''\{PLUGIN_DIR''\}/wifi.sh" \ - icon="􀙇" \ - background.color="''$''\{BACKGROUND_COLOR''\}" \ - background.corner_radius="7" \ - icon.padding_left="10" \ - label.padding_right="10" \ - blur_radius="30" \ - background.border_color="0x80c4a7e7" \ - background.border_width="1" \ - --subscribe wifi wifi_change \ - \ - --add item volume right \ - --set volume script="''$''\{PLUGIN_DIR''\}/volume.sh" \ - background.color="''$''\{BACKGROUND_COLOR''\}" \ - background.corner_radius="7" \ - icon.padding_left="10" \ - label.padding_right="10" \ - blur_radius="30" \ - background.border_color="0x80c4a7e7" \ - background.border_width="1" \ - --subscribe volume volume_change \ - \ - --add item battery right \ - --set battery script="''$''\{PLUGIN_DIR''\}/battery.sh" \ - update_freq="120" \ - background.color="''$''\{BACKGROUND_COLOR''\}" \ - background.corner_radius="7" \ - icon.padding_left="10" \ - label.padding_right="10" \ - blur_radius="30" \ - background.border_color="0x80c4a7e7" \ - background.border_width="1" \ - --subscribe battery system_woke power_source_change \ - - ##### Finalizing Setup ##### - # The below command is only needed at the end of the initial configuration to - # force all scripts to run the first time, it should never be run in an item script. - - sketchybar --update -'' + exec ${lib.getExe babashka} \ + --file ${sketchybar-config-script} \ + --plugin-dir ${plugin-dir} \ + --util-dir ${util-dir} \ + --get-menu-bar-height ${lib.getExe get-menu-bar-height} + ''; + runtimeInputs = [ + sketchybar + ]; + checkPhase = '' + ${lib.getExe clj-kondo} \ + --config '{:linters {:namespace-name-mismatch {:level :off}}}' \ + --lint ${sketchybar-config-script} + ''; +} diff --git a/modules/nix-darwin/yabai/sketchybar/plugins/battery.sh b/modules/nix-darwin/yabai/sketchybar/plugins/battery.sh index cc8fc7e..ac11871 100755 --- a/modules/nix-darwin/yabai/sketchybar/plugins/battery.sh +++ b/modules/nix-darwin/yabai/sketchybar/plugins/battery.sh @@ -2,12 +2,12 @@ source "${UTIL_DIR}/colors.sh" -BATT_PERCENT=$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1) +BATT_PERCENT=$(pmset -g batt | grep -Eo '[[:digit:]]+%' | cut -d% -f1) CHARGING=$(pmset -g batt | grep 'AC Power') sketchybar --set "${NAME}" icon.color=0xff989898 -if [ ${CHARGING} != "" ]; then +if [ "${CHARGING}" != "" ]; then case ${BATT_PERCENT} in 100) ICON="" diff --git a/modules/nix-darwin/yabai/yabairc b/modules/nix-darwin/yabai/yabairc index d82e6e7..bb92a0c 100644 --- a/modules/nix-darwin/yabai/yabairc +++ b/modules/nix-darwin/yabai/yabairc @@ -57,7 +57,7 @@ yabai -m config "external_bar" "all:32:0" \ "window_border_blur" "off" \ "window_border_width" "2" \ "window_border_hidpi" "off" \ - "window_border_radius" "11" \ + "window_border_radius" "0" \ "window_animation_duration" "0.22" \ "active_window_border_color" "0xffe1e3e4" \ "normal_window_border_color" "0xff2a2f38" \