From fbad532ae9e5541455ffb0829262a4859ff1165d Mon Sep 17 00:00:00 2001 From: Natalie Date: Sat, 3 May 2025 21:41:46 -0700 Subject: [PATCH] copy sketchybar conf --- .DS_Store | Bin 6148 -> 0 bytes files/sketchybar/executable_colors.sh | 26 ++ files/sketchybar/executable_icons.sh | 31 ++ files/sketchybar/executable_sketchybarrc | 73 ++++ files/sketchybar/helper/cpu.h | 120 ++++++ files/sketchybar/helper/executable_helper | Bin 0 -> 50952 bytes files/sketchybar/helper/helper.c | 32 ++ files/sketchybar/helper/makefile | 3 + files/sketchybar/helper/sketchybar.h | 227 ++++++++++ files/sketchybar/items/executable_apple.sh | 31 ++ files/sketchybar/items/executable_brew.sh | 14 + files/sketchybar/items/executable_calendar.sh | 12 + files/sketchybar/items/executable_cpu.sh | 37 ++ files/sketchybar/items/executable_divider.sh | 9 + .../sketchybar/items/executable_front_app.sh | 29 ++ files/sketchybar/items/executable_github.sh | 27 ++ .../items/executable_spaces.sh.tmpl | 39 ++ files/sketchybar/items/executable_spotify.sh | 125 ++++++ files/sketchybar/items/executable_volume.sh | 27 ++ files/sketchybar/plugins/executable_brew.sh | 21 + .../sketchybar/plugins/executable_calendar.sh | 3 + files/sketchybar/plugins/executable_github.sh | 87 ++++ .../sketchybar/plugins/executable_icon_map.sh | 381 +++++++++++++++++ files/sketchybar/plugins/executable_space.sh | 8 + .../sketchybar/plugins/executable_spotify.sh | 114 +++++ files/sketchybar/plugins/executable_volume.sh | 23 + .../plugins/executable_volume_click.sh | 9 + files/sketchybar/plugins/executable_yabai.sh | 76 ++++ files/sketchybar/plugins/executable_zen.sh | 45 ++ hosts/laptop/home.nix | 21 +- modules/macos/system.nix | 4 + modules/macos/tiling/aerospace.nix | 2 +- modules/macos/tiling/sketchybar-home.nix | 398 ++++++++++++++++++ modules/macos/tiling/sketchybar.nix | 146 +------ 34 files changed, 2049 insertions(+), 151 deletions(-) delete mode 100644 .DS_Store create mode 100644 files/sketchybar/executable_colors.sh create mode 100644 files/sketchybar/executable_icons.sh create mode 100644 files/sketchybar/executable_sketchybarrc create mode 100644 files/sketchybar/helper/cpu.h create mode 100644 files/sketchybar/helper/executable_helper create mode 100644 files/sketchybar/helper/helper.c create mode 100644 files/sketchybar/helper/makefile create mode 100644 files/sketchybar/helper/sketchybar.h create mode 100644 files/sketchybar/items/executable_apple.sh create mode 100644 files/sketchybar/items/executable_brew.sh create mode 100644 files/sketchybar/items/executable_calendar.sh create mode 100644 files/sketchybar/items/executable_cpu.sh create mode 100644 files/sketchybar/items/executable_divider.sh create mode 100644 files/sketchybar/items/executable_front_app.sh create mode 100644 files/sketchybar/items/executable_github.sh create mode 100644 files/sketchybar/items/executable_spaces.sh.tmpl create mode 100644 files/sketchybar/items/executable_spotify.sh create mode 100644 files/sketchybar/items/executable_volume.sh create mode 100644 files/sketchybar/plugins/executable_brew.sh create mode 100644 files/sketchybar/plugins/executable_calendar.sh create mode 100644 files/sketchybar/plugins/executable_github.sh create mode 100644 files/sketchybar/plugins/executable_icon_map.sh create mode 100644 files/sketchybar/plugins/executable_space.sh create mode 100644 files/sketchybar/plugins/executable_spotify.sh create mode 100644 files/sketchybar/plugins/executable_volume.sh create mode 100644 files/sketchybar/plugins/executable_volume_click.sh create mode 100644 files/sketchybar/plugins/executable_yabai.sh create mode 100644 files/sketchybar/plugins/executable_zen.sh create mode 100644 modules/macos/tiling/sketchybar-home.nix diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 140a77d1ac095724aa4222b51f02370376473033..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z>*NNhm@N3Oz1(E!fs76fYsx7cim+m70)3gE3p0lpabUXMG``#OHBl zcUuVNETS_o`_0bJX7fRIGmJ6rui^n?E@R9FMdWDI2)b)S4U^0PL1B$NTIY)>l~K(y zzte?#Z?id*EN4Y!{~ysJP4c4O|KyEkt9@Wuj@7ZAg1KA=MOdtIKU_ZG>{iM&+Sy@r zm(12v_vlJyMVMr>r7B3`8KgYkCs{1lzFcK-u4)4va2(s2y4}s@d^GBb!P&*OCpP0@ zzb8iH;dblT$0w(kH`AB&HIr|eNRB&4In=Np-}e?7!~iis3=jjvKpg|-2C+MJLGlp; z#K6C10M7>jis%_EHL9Zn2Gs%pw!p0fZ0selMi}%AmKq@f!gVR2F6E}h;JO_A!sK}d zOO3jmanpQo^W6;{AUOpG<9&UoD{-F+dFbF$Q>R z5=?w}DRZ}edp*2s1?V#<3g(q)fPh{334jTnBV85Lae+4Ec?L_3xC;7JIUxNAC_-o; I27Z8nFVR~?i~s-t diff --git a/files/sketchybar/executable_colors.sh b/files/sketchybar/executable_colors.sh new file mode 100644 index 0000000..627efac --- /dev/null +++ b/files/sketchybar/executable_colors.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env sh + +# Color Palette +export BLACK=0xff4c4f69 +export WHITE=0xffeff1f5 +export RED=0xffd20f39 +export GREEN=0xff40a02b +export BLUE=0xff1e66f5 +export YELLOW=0xffdf8e1d +export ORANGE=0xfffe640b +export MAGENTA=0xffea76cb +export GREY=0xff9ca0b0 +export TRANSPARENT=0xff000000 +export BLUE2=0xff7287fd + +# General bar colors +export BAR_COLOR=0xeff1f5ff # Color of the bar +export ICON_COLOR=0xff4c4f69 +export LABEL_COLOR=0xff4c4f69 # Color of all labels +export BACKGROUND_1=0xffbcc0cc +export BACKGROUND_2=0xffbcc0cc + +export POPUP_BACKGROUND_COLOR=$BLACK +export POPUP_BORDER_COLOR=$WHITE + +export SHADOW_COLOR=$BLACK diff --git a/files/sketchybar/executable_icons.sh b/files/sketchybar/executable_icons.sh new file mode 100644 index 0000000..65a7961 --- /dev/null +++ b/files/sketchybar/executable_icons.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env sh + +# General Icons +LOADING=􀖇 +APPLE=􀣺 +PREFERENCES=􀺽 +ACTIVITY=􀒓 +LOCK=􀒳 +BELL=􀋚 +BELL_DOT=􀝗 + +# Git Icons +GIT_ISSUE=􀍷 +GIT_DISCUSSION=􀒤 +GIT_PULL_REQUEST=􀙡 +GIT_COMMIT=􀡚 +GIT_INDICATOR=􀂓 + +# Spotify Icons +SPOTIFY_BACK=􀊎 +SPOTIFY_PLAY_PAUSE=􀊈 +SPOTIFY_NEXT=􀊐 +SPOTIFY_SHUFFLE=􀊝 +SPOTIFY_REPEAT=􀊞 + +# Yabai Icons +YABAI_STACK=􀏭 +YABAI_FULLSCREEN_ZOOM=􀏜 +YABAI_PARENT_ZOOM=􀥃 +YABAI_FLOAT=􀢌 +YABAI_GRID=􀧍 diff --git a/files/sketchybar/executable_sketchybarrc b/files/sketchybar/executable_sketchybarrc new file mode 100644 index 0000000..cedd4ff --- /dev/null +++ b/files/sketchybar/executable_sketchybarrc @@ -0,0 +1,73 @@ +#!/usr/bin/env sh + +source "$HOME/.config/sketchybar/colors.sh" # Loads all defined colors +source "$HOME/.config/sketchybar/icons.sh" # Loads all defined icons + +ITEM_DIR="$HOME/.config/sketchybar/items" # Directory where the items are configured +PLUGIN_DIR="$HOME/.config/sketchybar/plugins" # Directory where all the plugin scripts are stored + +FONT="SF Pro" # Needs to have Regular, Bold, Semibold, Heavy and Black variants +PADDINGS=3 # All paddings use this value (icon, label, background) + +# Setting up and starting the helper process +HELPER=git.felix.helper +killall helper +cd $HOME/.config/sketchybar/helper && make +$HOME/.config/sketchybar/helper/helper $HELPER > /dev/null 2>&1 & + +# Unload the macOS on screen indicator overlay for volume change +launchctl unload -F /System/Library/LaunchAgents/com.apple.OSDUIHelper.plist > /dev/null 2>&1 & + +# Setting up the general bar appearance and default values +sketchybar --bar height=50 \ + color=$BAR_COLOR \ + shadow=off \ + position=top \ + sticky=on \ + padding_right=7 \ + padding_left=7 \ + corner_radius=12 \ + y_offset=20 \ + margin=40 \ + blur_radius=0 \ + notch_width=0 \ + \ + --default updates=when_shown \ + icon.font="$FONT:Bold:14.0" \ + icon.color=$ICON_COLOR \ + icon.padding_left=$PADDINGS \ + icon.padding_right=$PADDINGS \ + label.font="$FONT:Semibold:13.0" \ + label.color=$LABEL_COLOR \ + label.padding_left=$PADDINGS \ + label.padding_right=$PADDINGS \ + background.padding_right=$PADDINGS \ + background.padding_left=$PADDINGS \ + background.height=26 \ + background.corner_radius=9 \ + popup.background.border_width=2 \ + popup.background.corner_radius=11 \ + popup.background.border_color=$POPUP_BORDER_COLOR \ + popup.background.color=$POPUP_BACKGROUND_COLOR \ + popup.background.shadow.drawing=on + +# Left +source "$ITEM_DIR/apple.sh" +source "$ITEM_DIR/spaces.sh" +source "$ITEM_DIR/front_app.sh" + +# Center +# source "$ITEM_DIR/spotify.sh" +source "$ITEM_DIR/calendar.sh" + +# Right +source "$ITEM_DIR/brew.sh" +# source "$ITEM_DIR/github.sh" +source "$ITEM_DIR/volume.sh" +source "$ITEM_DIR/divider.sh" +# source "$ITEM_DIR/cpu.sh" + +# Forcing all item scripts to run (never do this outside of sketchybarrc) +sketchybar --update + +echo "sketchybar configuation loaded.." diff --git a/files/sketchybar/helper/cpu.h b/files/sketchybar/helper/cpu.h new file mode 100644 index 0000000..d419702 --- /dev/null +++ b/files/sketchybar/helper/cpu.h @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + +static const char TOPPROC[32] = { "/bin/ps -Aceo pid,pcpu,comm -r" }; +static const char FILTER_PATTERN[16] = { "com.apple." }; + +struct cpu { + host_t host; + mach_msg_type_number_t count; + host_cpu_load_info_data_t load; + host_cpu_load_info_data_t prev_load; + bool has_prev_load; + + char command[256]; +}; + +static inline void cpu_init(struct cpu* cpu) { + cpu->host = mach_host_self(); + cpu->count = HOST_CPU_LOAD_INFO_COUNT; + cpu->has_prev_load = false; + snprintf(cpu->command, 100, ""); +} + +static inline void cpu_update(struct cpu* cpu) { + kern_return_t error = host_statistics(cpu->host, + HOST_CPU_LOAD_INFO, + (host_info_t)&cpu->load, + &cpu->count ); + + if (error != KERN_SUCCESS) { + printf("Error: Could not read cpu host statistics.\n"); + return; + } + + if (cpu->has_prev_load) { + uint32_t delta_user = cpu->load.cpu_ticks[CPU_STATE_USER] + - cpu->prev_load.cpu_ticks[CPU_STATE_USER]; + + uint32_t delta_system = cpu->load.cpu_ticks[CPU_STATE_SYSTEM] + - cpu->prev_load.cpu_ticks[CPU_STATE_SYSTEM]; + + uint32_t delta_idle = cpu->load.cpu_ticks[CPU_STATE_IDLE] + - cpu->prev_load.cpu_ticks[CPU_STATE_IDLE]; + + double user_perc = (double)delta_user / (double)(delta_system + + delta_user + + delta_idle); + + double sys_perc = (double)delta_system / (double)(delta_system + + delta_user + + delta_idle); + + double total_perc = user_perc + sys_perc; + + FILE* file; + char line[1024]; + + file = popen(TOPPROC, "r"); + if (!file) { + printf("Error: TOPPROC command errored out...\n" ); + return; + } + + fgets(line, sizeof(line), file); + fgets(line, sizeof(line), file); + + char* start = strstr(line, FILTER_PATTERN); + char topproc[32]; + uint32_t caret = 0; + for (int i = 0; i < sizeof(line); i++) { + if (start && i == start - line) { + i+=9; + continue; + } + + if (caret >= 28 && caret <= 30) { + topproc[caret++] = '.'; + continue; + } + if (caret > 30) break; + topproc[caret++] = line[i]; + if (line[i] == '\0') break; + } + + topproc[31] = '\0'; + + pclose(file); + + char color[16]; + if (total_perc >= .7) { + snprintf(color, 16, "%s", getenv("RED")); + } else if (total_perc >= .3) { + snprintf(color, 16, "%s", getenv("ORANGE")); + } else if (total_perc >= .1) { + snprintf(color, 16, "%s", getenv("YELLOW")); + } else { + snprintf(color, 16, "%s", getenv("LABEL_COLOR")); + } + + snprintf(cpu->command, 256, "--push cpu.sys %.2f " + "--push cpu.user %.2f " + "--set cpu.percent label=%.0f%% label.color=%s " + "--set cpu.top label=\"%s\"", + sys_perc, + user_perc, + total_perc*100., + color, + topproc ); + } + else { + snprintf(cpu->command, 256, ""); + } + + cpu->prev_load = cpu->load; + cpu->has_prev_load = true; +} diff --git a/files/sketchybar/helper/executable_helper b/files/sketchybar/helper/executable_helper new file mode 100644 index 0000000000000000000000000000000000000000..44fa0b6261b9eb1aaac6f3f981f7cbfdd9ff02bb GIT binary patch literal 50952 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 G?*9Ou^+hoN literal 0 HcmV?d00001 diff --git a/files/sketchybar/helper/helper.c b/files/sketchybar/helper/helper.c new file mode 100644 index 0000000..a03e677 --- /dev/null +++ b/files/sketchybar/helper/helper.c @@ -0,0 +1,32 @@ +#include "cpu.h" +#include "sketchybar.h" + +struct cpu g_cpu; + +void handler(env env) { + // Environment variables passed from sketchybar can be accessed as seen below + char* name = env_get_value_for_key(env, "NAME"); + char* sender = env_get_value_for_key(env, "SENDER"); + char* info = env_get_value_for_key(env, "INFO"); + char* selected = env_get_value_for_key(env, "SELECTED"); + + if ((strcmp(sender, "routine") == 0) + || (strcmp(sender, "forced") == 0)) { + // CPU graph updates + cpu_update(&g_cpu); + + if (strlen(g_cpu.command) > 0) sketchybar(g_cpu.command); + } +} + +int main (int argc, char** argv) { + cpu_init(&g_cpu); + + if (argc < 2) { + printf("Usage: provider \"\"\n"); + exit(1); + } + + event_server_begin(handler, argv[1]); + return 0; +} diff --git a/files/sketchybar/helper/makefile b/files/sketchybar/helper/makefile new file mode 100644 index 0000000..ac8721a --- /dev/null +++ b/files/sketchybar/helper/makefile @@ -0,0 +1,3 @@ + +helper: helper.c cpu.h sketchybar.h + clang -std=c99 -O3 helper.c -o helper diff --git a/files/sketchybar/helper/sketchybar.h b/files/sketchybar/helper/sketchybar.h new file mode 100644 index 0000000..82da2f6 --- /dev/null +++ b/files/sketchybar/helper/sketchybar.h @@ -0,0 +1,227 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +typedef char* env; + +#define MACH_HANDLER(name) void name(env env) +typedef MACH_HANDLER(mach_handler); + +struct mach_message { + mach_msg_header_t header; + mach_msg_size_t msgh_descriptor_count; + mach_msg_ool_descriptor_t descriptor; +}; + +struct mach_buffer { + struct mach_message message; + mach_msg_trailer_t trailer; +}; + +struct mach_server { + bool is_running; + mach_port_name_t task; + mach_port_t port; + mach_port_t bs_port; + + pthread_t thread; + mach_handler* handler; +}; + +static struct mach_server g_mach_server; +static mach_port_t g_mach_port = 0; + +static inline char* env_get_value_for_key(env env, char* key) { + uint32_t caret = 0; + for(;;) { + if (!env[caret]) break; + if (strcmp(&env[caret], key) == 0) + return &env[caret + strlen(&env[caret]) + 1]; + + caret += strlen(&env[caret]) + + strlen(&env[caret + strlen(&env[caret]) + 1]) + + 2; + } + return (char*)""; +} + +static inline mach_port_t mach_get_bs_port() { + mach_port_name_t task = mach_task_self(); + + mach_port_t bs_port; + if (task_get_special_port(task, + TASK_BOOTSTRAP_PORT, + &bs_port ) != KERN_SUCCESS) { + return 0; + } + + mach_port_t port; + if (bootstrap_look_up(bs_port, + "git.felix.sketchybar", + &port ) != KERN_SUCCESS) { + return 0; + } + + return port; +} + +static inline void mach_receive_message(mach_port_t port, struct mach_buffer* buffer, bool timeout) { + *buffer = (struct mach_buffer) { 0 }; + mach_msg_return_t msg_return; + if (timeout) + msg_return = mach_msg(&buffer->message.header, + MACH_RCV_MSG | MACH_RCV_TIMEOUT, + 0, + sizeof(struct mach_buffer), + port, + 100, + MACH_PORT_NULL ); + else + msg_return = mach_msg(&buffer->message.header, + MACH_RCV_MSG, + 0, + sizeof(struct mach_buffer), + port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL ); + + if (msg_return != MACH_MSG_SUCCESS) { + buffer->message.descriptor.address = NULL; + } +} + +static inline char* mach_send_message(mach_port_t port, char* message, uint32_t len) { + if (!message || !port) { + return NULL; + } + + mach_port_t response_port; + mach_port_name_t task = mach_task_self(); + if (mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, + &response_port ) != KERN_SUCCESS) { + return NULL; + } + + if (mach_port_insert_right(task, response_port, + response_port, + MACH_MSG_TYPE_MAKE_SEND)!= KERN_SUCCESS) { + return NULL; + } + + struct mach_message msg = { 0 }; + msg.header.msgh_remote_port = port; + msg.header.msgh_local_port = response_port; + msg.header.msgh_id = response_port; + msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, + MACH_MSG_TYPE_MAKE_SEND, + 0, + MACH_MSGH_BITS_COMPLEX ); + + msg.header.msgh_size = sizeof(struct mach_message); + msg.msgh_descriptor_count = 1; + msg.descriptor.address = message; + msg.descriptor.size = len * sizeof(char); + msg.descriptor.copy = MACH_MSG_VIRTUAL_COPY; + msg.descriptor.deallocate = false; + msg.descriptor.type = MACH_MSG_OOL_DESCRIPTOR; + + mach_msg(&msg.header, + MACH_SEND_MSG, + sizeof(struct mach_message), + 0, + MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL ); + + struct mach_buffer buffer = { 0 }; + mach_receive_message(response_port, &buffer, true); + if (buffer.message.descriptor.address) + return (char*)buffer.message.descriptor.address; + mach_msg_destroy(&buffer.message.header); + + return NULL; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +static inline bool mach_server_begin(struct mach_server* mach_server, mach_handler handler, char* bootstrap_name) { + mach_server->task = mach_task_self(); + + if (mach_port_allocate(mach_server->task, + MACH_PORT_RIGHT_RECEIVE, + &mach_server->port ) != KERN_SUCCESS) { + return false; + } + + if (mach_port_insert_right(mach_server->task, + mach_server->port, + mach_server->port, + MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS) { + return false; + } + + if (task_get_special_port(mach_server->task, + TASK_BOOTSTRAP_PORT, + &mach_server->bs_port) != KERN_SUCCESS) { + return false; + } + + if (bootstrap_register(mach_server->bs_port, + bootstrap_name, + mach_server->port ) != KERN_SUCCESS) { + return false; + } + + mach_server->handler = handler; + mach_server->is_running = true; + while (mach_server->is_running) { + struct mach_buffer* buffer = (struct mach_buffer*)malloc(sizeof(struct mach_buffer)); + mach_receive_message(mach_server->port, buffer, false); + mach_server->handler((env)buffer->message.descriptor.address); + mach_msg_destroy(&buffer->message.header); + } + + return true; +} +#pragma clang diagnostic pop + +static inline char* sketchybar(char* message) { + uint32_t message_length = strlen(message) + 1; + char formatted_message[message_length + 1]; + + char quote = '\0'; + uint32_t caret = 0; + for (int i = 0; i < message_length; ++i) { + if (message[i] == '"' || message[i] == '\'') { + if (quote == message[i]) quote = '\0'; + else quote = message[i]; + continue; + } + formatted_message[caret] = message[i]; + if (message[i] == ' ' && !quote) formatted_message[caret] = '\0'; + caret++; + } + + if (caret > 0 && formatted_message[caret] == '\0' + && formatted_message[caret - 1] == '\0') { + caret--; + } + + formatted_message[caret] = '\0'; + if (!g_mach_port) g_mach_port = mach_get_bs_port(); + char* response = mach_send_message(g_mach_port, + formatted_message, + caret + 1 ); + + if (response) return response; + else return (char*)""; +} + +static inline void event_server_begin(mach_handler event_handler, char* bootstrap_name) { + mach_server_begin(&g_mach_server, event_handler, bootstrap_name); +} diff --git a/files/sketchybar/items/executable_apple.sh b/files/sketchybar/items/executable_apple.sh new file mode 100644 index 0000000..22fb8e6 --- /dev/null +++ b/files/sketchybar/items/executable_apple.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env sh + +POPUP_OFF="sketchybar --set apple.logo popup.drawing=off" +POPUP_CLICK_SCRIPT="sketchybar --set \$NAME popup.drawing=toggle" + +sketchybar --add item apple.logo left \ + \ + --set apple.logo icon=$APPLE \ + icon.font="$FONT:Black:16.0" \ + icon.color=$BLUE2 \ + background.padding_right=25 \ + label.drawing=off \ + click_script="$POPUP_CLICK_SCRIPT" \ + \ + --add item apple.prefs popup.apple.logo \ + --set apple.prefs icon=$PREFERENCES \ + label="Preferences" \ + click_script="open -a 'System Preferences'; + $POPUP_OFF" \ + \ + --add item apple.activity popup.apple.logo \ + --set apple.activity icon=$ACTIVITY \ + label="Activity" \ + click_script="open -a 'Activity Monitor'; + $POPUP_OFF"\ + \ + --add item apple.lock popup.apple.logo \ + --set apple.lock icon=$LOCK \ + label="Lock Screen" \ + click_script="pmset displaysleepnow; + $POPUP_OFF" diff --git a/files/sketchybar/items/executable_brew.sh b/files/sketchybar/items/executable_brew.sh new file mode 100644 index 0000000..8314bb0 --- /dev/null +++ b/files/sketchybar/items/executable_brew.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env sh + +# Trigger the brew_udpate event when brew update or upgrade is run from cmdline +# e.g. via function in .zshrc + +sketchybar --add event brew_update \ + --add item brew right \ + --set brew script="$PLUGIN_DIR/brew.sh" \ + icon=󰏗 \ + label=? \ + label.color=$BLACK \ + background.padding_right=15 \ + --subscribe brew brew_update + diff --git a/files/sketchybar/items/executable_calendar.sh b/files/sketchybar/items/executable_calendar.sh new file mode 100644 index 0000000..ad140ca --- /dev/null +++ b/files/sketchybar/items/executable_calendar.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +sketchybar --add item calendar center \ + --set calendar icon=cal \ + icon.font="$FONT:Black:12.0" \ + icon.padding_right=0 \ + label.width=50 \ + label.align=right \ + background.padding_left=15 \ + update_freq=30 \ + script="$PLUGIN_DIR/calendar.sh" \ + click_script="$PLUGIN_DIR/zen.sh" diff --git a/files/sketchybar/items/executable_cpu.sh b/files/sketchybar/items/executable_cpu.sh new file mode 100644 index 0000000..4725b9f --- /dev/null +++ b/files/sketchybar/items/executable_cpu.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +sketchybar --add item cpu.top right \ + --set cpu.top label.font="$FONT:Semibold:7" \ + label=CPU \ + icon.drawing=off \ + width=0 \ + y_offset=6 \ + \ + --add item cpu.percent right \ + --set cpu.percent label.font="$FONT:Heavy:12" \ + label=CPU \ + y_offset=-4 \ + width=40 \ + icon.drawing=off \ + update_freq=2 \ + mach_helper="$HELPER" \ + \ + --add graph cpu.sys right 100 \ + --set cpu.sys width=0 \ + graph.color=$RED \ + graph.fill_color=$RED \ + label.drawing=off \ + icon.drawing=off \ + background.padding_left=10 \ + background.height=30 \ + background.drawing=on \ + background.color=$TRANSPARENT \ + \ + --add graph cpu.user right 100 \ + --set cpu.user graph.color=$BLUE \ + label.drawing=off \ + icon.drawing=off \ + background.padding_left=10 \ + background.height=30 \ + background.drawing=on \ + background.color=$TRANSPARENT diff --git a/files/sketchybar/items/executable_divider.sh b/files/sketchybar/items/executable_divider.sh new file mode 100644 index 0000000..2176613 --- /dev/null +++ b/files/sketchybar/items/executable_divider.sh @@ -0,0 +1,9 @@ +sketchybar --add bracket status brew volume volume_alias \ + --set status background.color=$WHITE + +# sketchybar --add item divider right \ +# --set divider label.drawing=off \ +# icon=􀫰 \ +# icon.font="$FONT:Black:22.0" \ +# background.padding_left=15 \ +# background.padding_right=20 diff --git a/files/sketchybar/items/executable_front_app.sh b/files/sketchybar/items/executable_front_app.sh new file mode 100644 index 0000000..31cec8b --- /dev/null +++ b/files/sketchybar/items/executable_front_app.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env sh + +FRONT_APP_SCRIPT='sketchybar --set $NAME label="$INFO"' + +sketchybar --add event window_focus \ + --add event windows_on_spaces \ + --add item system.yabai left \ + --set system.yabai script="$PLUGIN_DIR/yabai.sh" \ + icon.font="$FONT:Bold:16.0" \ + label.drawing=off \ + icon.width=30 \ + icon=$YABAI_GRID \ + icon.color=$BLACK \ + updates=on \ + associated_display=active \ + --subscribe system.yabai window_focus \ + windows_on_spaces \ + mouse.clicked \ + \ + --add item front_app left \ + --set front_app script="$FRONT_APP_SCRIPT" \ + icon.drawing=off \ + background.padding_left=0 \ + background.padding_right=10 \ + label.color=$BLACK \ + label.font="$FONT:Black:12.0" \ + associated_display=active \ + --subscribe front_app front_app_switched + diff --git a/files/sketchybar/items/executable_github.sh b/files/sketchybar/items/executable_github.sh new file mode 100644 index 0000000..c49a931 --- /dev/null +++ b/files/sketchybar/items/executable_github.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env sh + +POPUP_CLICK_SCRIPT="sketchybar --set \$NAME popup.drawing=toggle" + +sketchybar --add item github.bell right \ + --set github.bell update_freq=180 \ + icon.font="$FONT:Bold:15.0" \ + icon=$BELL \ + icon.color=$BLUE \ + label=$LOADING \ + label.highlight_color=$BLUE \ + popup.align=right \ + script="$PLUGIN_DIR/github.sh" \ + click_script="$POPUP_CLICK_SCRIPT" \ + --subscribe github.bell mouse.entered \ + mouse.exited \ + mouse.exited.global \ + \ + --add item github.template popup.github.bell \ + --set github.template drawing=off \ + background.corner_radius=12 \ + background.padding_left=7 \ + background.padding_right=7 \ + background.color=$BLACK \ + background.drawing=off \ + icon.background.height=2 \ + icon.background.y_offset=-12 diff --git a/files/sketchybar/items/executable_spaces.sh.tmpl b/files/sketchybar/items/executable_spaces.sh.tmpl new file mode 100644 index 0000000..6261efc --- /dev/null +++ b/files/sketchybar/items/executable_spaces.sh.tmpl @@ -0,0 +1,39 @@ +#!/usr/bin/env sh + +SPACE_ICONS=("1" "2" "3" "4" "5" "6" "7" "8" "9" "10") +SPACE_CLICK_SCRIPT="yabai -m space --focus \$SID 2>/dev/null" + +sid=0 +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]} \ + icon.padding_left=22 \ + icon.padding_right=22 \ + label.padding_right=33 \ + icon.highlight_color=$WHITE \ + icon.color=0xff4c566a \ + background.padding_left=-8 \ + background.padding_right=-8 \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + label.font="JetBrainsMono Nerd Font:Regular:16.0" \ + label.background.height=26 \ + label.background.drawing=on \ + label.background.color=$BACKGROUND_2 \ + label.background.corner_radius=9 \ + label.drawing=off \ + script="$PLUGIN_DIR/space.sh" \ + click_script="$SPACE_CLICK_SCRIPT" +done + +sketchybar --add item separator left \ + --set separator icon= \ + icon.font="JetBrainsMono Nerd Font:Regular:16.0" \ + background.padding_left=26 \ + background.padding_right=15 \ + label.drawing=off \ + associated_display=active \ + icon.color=$GREEN diff --git a/files/sketchybar/items/executable_spotify.sh b/files/sketchybar/items/executable_spotify.sh new file mode 100644 index 0000000..22dca72 --- /dev/null +++ b/files/sketchybar/items/executable_spotify.sh @@ -0,0 +1,125 @@ +SPOTIFY_EVENT="com.spotify.client.PlaybackStateChanged" +POPUP_SCRIPT="sketchybar -m --set spotify.anchor popup.drawing=toggle" + +sketchybar --add event spotify_change $SPOTIFY_EVENT \ + --add item spotify.anchor center \ + --set spotify.anchor script="$PLUGIN_DIR/spotify.sh" \ + click_script="$POPUP_SCRIPT" \ + background.padding_left=22 \ + popup.horizontal=on \ + popup.align=center \ + popup.height=120 \ + icon=􁁒 \ + icon.font="$FONT:Regular:25.0" \ + icon.drawing=off \ + label.drawing=off \ + drawing=off \ + --subscribe spotify.anchor mouse.entered mouse.exited \ + mouse.exited.global \ + \ + --add item spotify.cover popup.spotify.anchor \ + --set spotify.cover script="$PLUGIN_DIR/spotify.sh" \ + label.drawing=off \ + icon.drawing=off \ + background.padding_left=12 \ + background.padding_right=10 \ + background.image.scale=0.15 \ + background.image.drawing=on \ + background.drawing=on \ + \ + --add item spotify.title popup.spotify.anchor \ + --set spotify.title icon.drawing=off \ + background.padding_left=0 \ + background.padding_right=0 \ + width=0 \ + label.font="$FONT:Heavy:14.0" \ + y_offset=40 \ + \ + --add item spotify.artist popup.spotify.anchor \ + --set spotify.artist icon.drawing=off \ + y_offset=20 \ + background.padding_left=0 \ + background.padding_right=0 \ + width=0 \ + \ + --add item spotify.album popup.spotify.anchor \ + --set spotify.album icon.drawing=off \ + background.padding_left=0 \ + background.padding_right=0 \ + y_offset=3 \ + width=0 \ + \ + --add item spotify.shuffle popup.spotify.anchor \ + --set spotify.shuffle icon=􀊝 \ + icon.padding_left=5 \ + icon.padding_right=5 \ + icon.color=$BLACK \ + icon.highlight_color=$MAGENTA \ + label.drawing=off \ + script="$PLUGIN_DIR/spotify.sh" \ + y_offset=-30 \ + --subscribe spotify.shuffle mouse.clicked \ + \ + --add item spotify.back popup.spotify.anchor \ + --set spotify.back icon=􀊎 \ + icon.padding_left=5 \ + icon.padding_right=5 \ + icon.color=$BLACK \ + script="$PLUGIN_DIR/spotify.sh" \ + label.drawing=off \ + y_offset=-30 \ + --subscribe spotify.back mouse.clicked \ + \ + --add item spotify.play popup.spotify.anchor \ + --set spotify.play icon=􀊔 \ + background.height=40 \ + background.corner_radius=20 \ + width=40 \ + align=center \ + background.color=$BLACK \ + background.border_color=$WHITE \ + background.border_width=0 \ + background.drawing=on \ + icon.padding_left=4 \ + icon.padding_right=5 \ + icon.color=$WHITE \ + updates=on \ + label.drawing=off \ + script="$PLUGIN_DIR/spotify.sh" \ + y_offset=-30 \ + --subscribe spotify.play mouse.clicked spotify_change \ + \ + --add item spotify.next popup.spotify.anchor \ + --set spotify.next icon=􀊐 \ + icon.padding_left=5 \ + icon.padding_right=10 \ + icon.color=$BLACK \ + label.drawing=off \ + script="$PLUGIN_DIR/spotify.sh" \ + y_offset=-30 \ + --subscribe spotify.next mouse.clicked \ + \ + --add item spotify.repeat popup.spotify.anchor \ + --set spotify.repeat icon=􀊞 \ + icon.highlight_color=$MAGENTA \ + icon.padding_left=5 \ + icon.padding_right=10 \ + icon.color=$BLACK \ + label.drawing=off \ + script="$PLUGIN_DIR/spotify.sh" \ + y_offset=-30 \ + --subscribe spotify.repeat mouse.clicked \ + \ + --add item spotify.spacer popup.spotify.anchor \ + --set spotify.spacer width=5 \ + \ + --add bracket spotify spotify.shuffle \ + spotify.back \ + spotify.play \ + spotify.next \ + spotify.repeat \ + --set spotify background.color=$GREEN \ + background.corner_radius=11 \ + background.drawing=on \ + y_offset=-30 \ + drawing=off diff --git a/files/sketchybar/items/executable_volume.sh b/files/sketchybar/items/executable_volume.sh new file mode 100644 index 0000000..cd6c854 --- /dev/null +++ b/files/sketchybar/items/executable_volume.sh @@ -0,0 +1,27 @@ +sketchybar --add item volume right \ + --set volume script="$PLUGIN_DIR/volume.sh" \ + updates=on \ + icon.background.drawing=on \ + icon.background.color=$GREEN \ + icon.background.height=8 \ + icon.background.corner_radius=3 \ + icon.width=0 \ + icon.align=right \ + label.drawing=off \ + background.drawing=on \ + background.color=$BACKGROUND_2 \ + background.height=8 \ + background.corner_radius=3 \ + align=left \ + --subscribe volume volume_change + +sketchybar --add alias "Control Center,Sound" right \ + --rename "Control Center,Sound" volume_alias \ + --set volume_alias icon.drawing=off \ + label.drawing=off \ + alias.color=$WHITE \ + background.padding_right=0 \ + background.padding_left=5 \ + width=50 \ + align=right \ + click_script="$PLUGIN_DIR/volume_click.sh" diff --git a/files/sketchybar/plugins/executable_brew.sh b/files/sketchybar/plugins/executable_brew.sh new file mode 100644 index 0000000..ccc8fad --- /dev/null +++ b/files/sketchybar/plugins/executable_brew.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh + +source "$HOME/.config/sketchybar/colors.sh" + +COUNT=$(brew outdated | wc -l | tr -d ' ') + +COLOR=$RED + +case "$COUNT" in + [3-5][0-9]) COLOR=$ORANGE + ;; + [1-2][0-9]) COLOR=$YELLOW + ;; + [1-9]) COLOR=$BLACK + ;; + 0) COLOR=$GREEN + COUNT=􀆅 + ;; +esac + +sketchybar --set $NAME label=$COUNT icon.color=$COLOR diff --git a/files/sketchybar/plugins/executable_calendar.sh b/files/sketchybar/plugins/executable_calendar.sh new file mode 100644 index 0000000..23dea12 --- /dev/null +++ b/files/sketchybar/plugins/executable_calendar.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +sketchybar --set $NAME icon="$(date '+%a %d. %b')" label="$(date '+%H:%M')" diff --git a/files/sketchybar/plugins/executable_github.sh b/files/sketchybar/plugins/executable_github.sh new file mode 100644 index 0000000..a26f9e3 --- /dev/null +++ b/files/sketchybar/plugins/executable_github.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +update() { + source "$HOME/.config/sketchybar/colors.sh" + source "$HOME/.config/sketchybar/icons.sh" + + NOTIFICATIONS="$(gh api notifications)" + COUNT="$(echo "$NOTIFICATIONS" | jq 'length')" + args=() + if [ "$NOTIFICATIONS" = "[]" ]; then + args+=(--set $NAME icon=$BELL label="0") + else + args+=(--set $NAME icon=$BELL_DOT label="$COUNT") + fi + + PREV_COUNT=$(sketchybar --query github.bell | jq -r .label.value) + # For sound to play around with: + # afplay /System/Library/Sounds/Morse.aiff + + args+=(--remove '/github.notification\.*/') + + COUNTER=0 + COLOR=$BLUE + args+=(--set github.bell icon.color=$COLOR) + + while read -r repo url type title + do + COUNTER=$((COUNTER + 1)) + IMPORTANT="$(echo "$title" | egrep -i "(deprecat|break|broke)")" + COLOR=$BLUE + PADDING=0 + + if [ "${repo}" = "" ] && [ "${title}" = "" ]; then + repo="Note" + title="No new notifications" + fi + case "${type}" in + "'Issue'") COLOR=$GREEN; ICON=$GIT_ISSUE; URL="$(gh api "$(echo "${url}" | sed -e "s/^'//" -e "s/'$//")" | jq .html_url)" + ;; + "'Discussion'") COLOR=$WHITE; ICON=$GIT_DISCUSSION; URL="https://www.github.com/notifications" + ;; + "'PullRequest'") COLOR=$MAGENTA; ICON=$GIT_PULL_REQUEST; URL="$(gh api "$(echo "${url}" | sed -e "s/^'//" -e "s/'$//")" | jq .html_url)" + ;; + "'Commit'") COLOR=$WHITE; ICON=$GIT_COMMIT; URL="$(gh api "$(echo "${url}" | sed -e "s/^'//" -e "s/'$//")" | jq .html_url)" + ;; + esac + + if [ "$IMPORTANT" != "" ]; then + COLOR=$RED + ICON=􀁞 + args+=(--set github.bell icon.color=$COLOR) + fi + + args+=(--clone github.notification.$COUNTER github.template \ + --set github.notification.$COUNTER label="$(echo "$title" | sed -e "s/^'//" -e "s/'$//")" \ + icon="$ICON $(echo "$repo" | sed -e "s/^'//" -e "s/'$//"):" \ + icon.padding_left="$PADDING" \ + label.padding_right="$PADDING" \ + icon.color=$COLOR \ + position=popup.github.bell \ + icon.background.color=$COLOR \ + drawing=on \ + click_script="open $URL; + sketchybar --set github.bell popup.drawing=off") + done <<< "$(echo "$NOTIFICATIONS" | jq -r '.[] | [.repository.name, .subject.latest_comment_url, .subject.type, .subject.title] | @sh')" + + sketchybar -m "${args[@]}" + + if [ $COUNT -gt $PREV_COUNT ] 2>/dev/null || [ "$SENDER" = "forced" ]; then + sketchybar --animate tanh 15 --set github.bell label.y_offset=5 label.y_offset=0 + fi +} + +popup() { + sketchybar --set $NAME popup.drawing=$1 +} + +case "$SENDER" in + "routine"|"forced") update + ;; + "mouse.entered") popup on + ;; + "mouse.exited"|"mouse.exited.global") popup off + ;; + "mouse.clicked") popup toggle + ;; +esac diff --git a/files/sketchybar/plugins/executable_icon_map.sh b/files/sketchybar/plugins/executable_icon_map.sh new file mode 100644 index 0000000..7252f6f --- /dev/null +++ b/files/sketchybar/plugins/executable_icon_map.sh @@ -0,0 +1,381 @@ +case "$1" in +"Brave Browser") + icon_result=":brave_browser:" + ;; +"Keyboard Maestro") + icon_result=":keyboard_maestro:" + ;; +"Min") + icon_result=":min_browser:" + ;; +"Final Cut Pro") + icon_result=":final_cut_pro:" + ;; +"FaceTime") + icon_result=":face_time:" + ;; +"Affinity Publisher") + icon_result=":affinity_publisher:" + ;; +"Messages" | "Nachrichten") + icon_result=":messages:" + ;; +"Tweetbot" | "Twitter") + icon_result=":twitter:" + ;; +"ClickUp") + icon_result=":click_up:" + ;; +"KeePassXC") + icon_result=":kee_pass_x_c:" + ;; +"Microsoft Edge") + icon_result=":microsoft_edge:" + ;; +"VLC") + icon_result=":vlc:" + ;; +"Emacs") + icon_result=":emacs:" + ;; +"Thunderbird") + icon_result=":thunderbird:" + ;; +"Notes") + icon_result=":notes:" + ;; +"Caprine") + icon_result=":caprine:" + ;; +"Zulip") + icon_result=":zulip:" + ;; +"Spark") + icon_result=":spark:" + ;; +"Microsoft To Do" | "Things") + icon_result=":things:" + ;; +"DEVONthink 3") + icon_result=":devonthink3:" + ;; +"GitHub Desktop") + icon_result=":git_hub:" + ;; +"App Store") + icon_result=":app_store:" + ;; +"Chromium" | "Google Chrome" | "Google Chrome Canary") + icon_result=":google_chrome:" + ;; +"zoom.us") + icon_result=":zoom:" + ;; +"MoneyMoney") + icon_result=":bank:" + ;; +"Color Picker") + icon_result=":color_picker:" + ;; +"Microsoft Word") + icon_result=":microsoft_word:" + ;; +"Iris") + icon_result=":iris:" + ;; +"WebStorm") + icon_result=":web_storm:" + ;; +"Neovide" | "MacVim" | "Vim" | "VimR") + icon_result=":vim:" + ;; +"Sublime Text") + icon_result=":sublime_text:" + ;; +"PomoDone App") + icon_result=":pomodone:" + ;; +"Setapp") + icon_result=":setapp:" + ;; +"qutebrowser") + icon_result=":qute_browser:" + ;; +"Mattermost") + icon_result=":mattermost:" + ;; +"Notability") + icon_result=":notability:" + ;; +"WhatsApp") + icon_result=":whats_app:" + ;; +"OBS") + icon_result=":obsstudio:" + ;; +"Parallels Desktop") + icon_result=":parallels:" + ;; +"VMware Fusion") + icon_result=":vmware_fusion:" + ;; +"Pine") + icon_result=":pine:" + ;; +"Microsoft Excel") + icon_result=":microsoft_excel:" + ;; +"Microsoft PowerPoint") + icon_result=":microsoft_power_point:" + ;; +"Matlab") + icon_result=":matlab:" + ;; +"Numbers") + icon_result=":numbers:" + ;; +"Default") + icon_result=":default:" + ;; +"Element") + icon_result=":element:" + ;; +"Bear") + icon_result=":bear:" + ;; +"TeamSpeak 3") + icon_result=":team_speak:" + ;; +"Airmail") + icon_result=":airmail:" + ;; +"Firefox Developer Edition" | "Firefox Nightly") + icon_result=":firefox_developer_edition:" + ;; +"Trello") + icon_result=":trello:" + ;; +"TickTick") + icon_result=":tick_tick:" + ;; +"Notion") + icon_result=":notion:" + ;; +"Live") + icon_result=":ableton:" + ;; +"Evernote Legacy") + icon_result=":evernote_legacy:" + ;; +"Calendar" | "Fantastical") + icon_result=":calendar:" + ;; +"Android Studio") + icon_result=":android_studio:" + ;; +"Xcode") + icon_result=":xcode:" + ;; +"Slack") + icon_result=":slack:" + ;; +"Sequel Pro") + icon_result=":sequel_pro:" + ;; +"Bitwarden") + icon_result=":bit_warden:" + ;; +"System Preferences") + icon_result=":gear:" + ;; +"Discord" | "Discord Canary" | "Discord PTB") + icon_result=":discord:" + ;; +"Vivaldi") + icon_result=":vivaldi:" + ;; +"Firefox") + icon_result=":firefox:" + ;; +"Skype") + icon_result=":skype:" + ;; +"Dropbox") + icon_result=":dropbox:" + ;; +"微信") + icon_result=":wechat:" + ;; +"Typora") + icon_result=":text:" + ;; +"Blender") + icon_result=":blender:" + ;; +"Canary Mail" | "HEY" | "Mail" | "Mailspring" | "MailMate" | "邮件") + icon_result=":mail:" + ;; +"Safari" | "Safari Technology Preview") + icon_result=":safari:" + ;; +"Telegram") + icon_result=":telegram:" + ;; +"Keynote") + icon_result=":keynote:" + ;; +"Reeder") + icon_result=":reeder5:" + ;; +"Spotify") + icon_result=":spotify:" + ;; +"MAMP" | "MAMP PRO") + icon_result=":mamp:" + ;; +"Figma") + icon_result=":figma:" + ;; +"Joplin") + icon_result=":joplin:" + ;; +"Spotlight") + icon_result=":spotlight:" + ;; +"Music") + icon_result=":music:" + ;; +"Insomnia") + icon_result=":insomnia:" + ;; +"TIDAL") + icon_result=":tidal:" + ;; +"Alfred") + icon_result=":alfred:" + ;; +"Pages") + icon_result=":pages:" + ;; +"Folx") + icon_result=":folx:" + ;; +"Android Messages") + icon_result=":android_messages:" + ;; +"mpv") + icon_result=":mpv:" + ;; +"网易云音乐") + icon_result=":netease_music:" + ;; +"Transmit") + icon_result=":transmit:" + ;; +"Pi-hole Remote") + icon_result=":pihole:" + ;; +"Nova") + icon_result=":nova:" + ;; +"Affinity Designer") + icon_result=":affinity_designer:" + ;; +"IntelliJ IDEA") + icon_result=":idea:" + ;; +"Drafts") + icon_result=":drafts:" + ;; +"Audacity") + icon_result=":audacity:" + ;; +"Affinity Photo") + icon_result=":affinity_photo:" + ;; +"Atom") + icon_result=":atom:" + ;; +"Obsidian") + icon_result=":obsidian:" + ;; +"CleanMyMac X") + icon_result=":desktop:" + ;; +"Zotero") + icon_result=":zotero:" + ;; +"Todoist") + icon_result=":todoist:" + ;; +"LibreWolf") + icon_result=":libre_wolf:" + ;; +"Grammarly Editor") + icon_result=":grammarly:" + ;; +"OmniFocus") + icon_result=":omni_focus:" + ;; +"Reminders") + icon_result=":reminders:" + ;; +"Preview" | "Skim" | "zathura") + icon_result=":pdf:" + ;; +"1Password 7") + icon_result=":one_password:" + ;; +"Code" | "Code - Insiders") + icon_result=":code:" + ;; +"VSCodium") + icon_result=":vscodium:" + ;; +"Tower") + icon_result=":tower:" + ;; +"Calibre") + icon_result=":book:" + ;; +"Finder" | "访达") + icon_result=":finder:" + ;; +"Linear") + icon_result=":linear:" + ;; +"League of Legends") + icon_result=":league_of_legends:" + ;; +"Zeplin") + icon_result=":zeplin:" + ;; +"Signal") + icon_result=":signal:" + ;; +"Podcasts") + icon_result=":podcasts:" + ;; +"Alacritty" | "Hyper" | "iTerm2" | "kitty" | "Terminal" | "WezTerm") + icon_result=":terminal:" + ;; +"Tor Browser") + icon_result=":tor_browser:" + ;; +"Kakoune") + icon_result=":kakoune:" + ;; +"GrandTotal" | "Receipts") + icon_result=":dollar:" + ;; +"Sketch") + icon_result=":sketch:" + ;; +"Sequel Ace") + icon_result=":sequel_ace:" + ;; +*) + icon_result=":default:" + ;; +esac +echo $icon_result diff --git a/files/sketchybar/plugins/executable_space.sh b/files/sketchybar/plugins/executable_space.sh new file mode 100644 index 0000000..9de0e4e --- /dev/null +++ b/files/sketchybar/plugins/executable_space.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +WIDTH="dynamic" +if [ "$SELECTED" = "true" ]; then + WIDTH="0" +fi + +sketchybar --animate tanh 20 --set $NAME icon.highlight=$SELECTED label.width=$WIDTH diff --git a/files/sketchybar/plugins/executable_spotify.sh b/files/sketchybar/plugins/executable_spotify.sh new file mode 100644 index 0000000..af66018 --- /dev/null +++ b/files/sketchybar/plugins/executable_spotify.sh @@ -0,0 +1,114 @@ +#!/bin/sh + +next () +{ + osascript -e 'tell application "Spotify" to play next track' +} + +back () +{ + osascript -e 'tell application "Spotify" to play previous track' +} + +play () +{ + osascript -e 'tell application "Spotify" to playpause' +} + +repeat () +{ + REPEAT=$(osascript -e 'tell application "Spotify" to get repeating') + if [ "$REPEAT" = "false" ]; then + sketchybar -m --set spotify.repeat icon.highlight=on + osascript -e 'tell application "Spotify" to set repeating to true' + else + sketchybar -m --set spotify.repeat icon.highlight=off + osascript -e 'tell application "Spotify" to set repeating to false' + fi +} + +shuffle () +{ + SHUFFLE=$(osascript -e 'tell application "Spotify" to get shuffling') + if [ "$SHUFFLE" = "false" ]; then + sketchybar -m --set spotify.shuffle icon.highlight=on + osascript -e 'tell application "Spotify" to set shuffling to true' + else + sketchybar -m --set spotify.shuffle icon.highlight=off + osascript -e 'tell application "Spotify" to set shuffling to false' + fi +} + +update () +{ + PLAYING=1 + if [ "$(echo "$INFO" | jq -r '.["Player State"]')" = "Playing" ]; then + PLAYING=0 + TRACK="$(echo "$INFO" | jq -r .Name | sed 's/\(.\{20\}\).*/\1.../')" + ARTIST="$(echo "$INFO" | jq -r .Artist | sed 's/\(.\{20\}\).*/\1.../')" + ALBUM="$(echo "$INFO" | jq -r .Album | sed 's/\(.\{25\}\).*/\1.../')" + SHUFFLE=$(osascript -e 'tell application "Spotify" to get shuffling') + REPEAT=$(osascript -e 'tell application "Spotify" to get repeating') + COVER=$(osascript -e 'tell application "Spotify" to get artwork url of current track') + fi + + args=() + if [ $PLAYING -eq 0 ]; then + curl -s --max-time 20 "$COVER" -o /tmp/cover.jpg + if [ "$ARTIST" == "" ]; then + args+=(--set spotify.title label="$TRACK" drawing=on \ + --set spotify.album label="Podcast" drawing=on \ + --set spotify.artist label="$ALBUM" drawing=on ) + else + args+=(--set spotify.title label="$TRACK" drawing=on \ + --set spotify.album label="$ALBUM" drawing=on \ + --set spotify.artist label="$ARTIST" drawing=on) + fi + args+=(--set spotify.play icon=􀊆 \ + --set spotify.shuffle icon.highlight=$SHUFFLE \ + --set spotify.repeat icon.highlight=$REPEAT \ + --set spotify.cover background.image="/tmp/cover.jpg" \ + background.color=0x00000000 \ + --set spotify.anchor icon.drawing=on \ + drawing=on \ + --set spotify drawing=on ) + else + args+=(--set spotify.title drawing=off \ + --set spotify.artist drawing=off \ + --set spotify.anchor drawing=off popup.drawing=off \ + --set spotify.play icon=􀊄 ) + fi + sketchybar -m "${args[@]}" +} + +mouse_clicked () { + case "$NAME" in + "spotify.next") next + ;; + "spotify.back") back + ;; + "spotify.play") play + ;; + "spotify.shuffle") shuffle + ;; + "spotify.repeat") repeat + ;; + *) exit + ;; + esac +} + +popup () { + sketchybar --set spotify.anchor popup.drawing=$1 +} + +case "$SENDER" in + "mouse.clicked") mouse_clicked + ;; + "mouse.entered") popup on + ;; + "mouse.exited"|"mouse.exited.global") popup off + ;; + *) update + ;; +esac diff --git a/files/sketchybar/plugins/executable_volume.sh b/files/sketchybar/plugins/executable_volume.sh new file mode 100644 index 0000000..080bfc7 --- /dev/null +++ b/files/sketchybar/plugins/executable_volume.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +WIDTH=100 + +volume_change() { + INITIAL_WIDTH=$(sketchybar --query $NAME | jq ".icon.width") + if [ "$INITIAL_WIDTH" -eq "0" ]; then + sketchybar --animate tanh 30 --set $NAME width=$WIDTH icon.width=$INFO + else + sketchybar --set $NAME icon.width=$INFO width=$WIDTH + fi + + sleep 5 + FINAL_WIDTH=$(sketchybar --query $NAME | jq ".icon.width") + if [ "$FINAL_WIDTH" -eq "$INFO" ]; then + sketchybar --animate tanh 30 --set $NAME width=0 icon.width=0 + fi +} + +case "$SENDER" in + "volume_change") volume_change + ;; +esac diff --git a/files/sketchybar/plugins/executable_volume_click.sh b/files/sketchybar/plugins/executable_volume_click.sh new file mode 100644 index 0000000..c0f2b38 --- /dev/null +++ b/files/sketchybar/plugins/executable_volume_click.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +MUTED=$(osascript -e 'output muted of (get volume settings)') + +if [ "$MUTED" = "false" ]; then + osascript -e 'set volume output muted true' +else + osascript -e 'set volume output muted false' +fi diff --git a/files/sketchybar/plugins/executable_yabai.sh b/files/sketchybar/plugins/executable_yabai.sh new file mode 100644 index 0000000..5ae2ae1 --- /dev/null +++ b/files/sketchybar/plugins/executable_yabai.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +window_state() { + source "$HOME/.config/sketchybar/colors.sh" + source "$HOME/.config/sketchybar/icons.sh" + + WINDOW=$(yabai -m query --windows --window) + CURRENT=$(echo "$WINDOW" | jq '.["stack-index"]') + + args=() + if [[ $CURRENT -gt 0 ]]; then + LAST=$(yabai -m query --windows --window stack.last | jq '.["stack-index"]') + args+=(--set $NAME icon=$YABAI_STACK icon.color=$RED label.drawing=on label=$(printf "[%s/%s]" "$CURRENT" "$LAST")) + yabai -m config active_window_border_color $RED > /dev/null 2>&1 & + + else + args+=(--set $NAME label.drawing=off) + case "$(echo "$WINDOW" | jq '.["is-floating"]')" in + "false") + if [ "$(echo "$WINDOW" | jq '.["has-fullscreen-zoom"]')" = "true" ]; then + args+=(--set $NAME icon=$YABAI_FULLSCREEN_ZOOM icon.color=$GREEN) + yabai -m config active_window_border_color $GREEN > /dev/null 2>&1 & + elif [ "$(echo "$WINDOW" | jq '.["has-parent-zoom"]')" = "true" ]; then + args+=(--set $NAME icon=$YABAI_PARENT_ZOOM icon.color=$BLUE) + yabai -m config active_window_border_color $BLUE > /dev/null 2>&1 & + else + args+=(--set $NAME icon=$YABAI_GRID icon.color=$ORANGE) + yabai -m config active_window_border_color $WHITE > /dev/null 2>&1 & + fi + ;; + "true") + args+=(--set $NAME icon=$YABAI_FLOAT icon.color=$MAGENTA) + yabai -m config active_window_border_color $MAGENTA > /dev/null 2>&1 & + ;; + esac + fi + + sketchybar -m "${args[@]}" +} + +windows_on_spaces () { + CURRENT_SPACES="$(yabai -m query --displays | jq -r '.[].spaces | @sh')" + + args=() + while read -r line + do + for space in $line + do + icon_strip=" " + apps=$(yabai -m query --windows --space $space | jq -r ".[].app") + for app in $apps + do + icon_strip+=" $($HOME/.config/sketchybar/plugins/icon_map.sh "$app")" + done + args+=(--set space.$space label="$icon_strip" label.drawing=on) + done + done <<< "$CURRENT_SPACES" + + sketchybar -m "${args[@]}" +} + +mouse_clicked() { + yabai -m window --toggle float + update +} + +case "$SENDER" in + "mouse.clicked") mouse_clicked + ;; + "forced") exit 0 + ;; + "window_focus") window_state + ;; + "windows_on_spaces") windows_on_spaces + ;; +esac diff --git a/files/sketchybar/plugins/executable_zen.sh b/files/sketchybar/plugins/executable_zen.sh new file mode 100644 index 0000000..25af993 --- /dev/null +++ b/files/sketchybar/plugins/executable_zen.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +zen_on() { + sketchybar --set github.bell drawing=off \ + --set apple.logo drawing=off \ + --set '/cpu.*/' drawing=off \ + --set calendar icon.drawing=off \ + --set system.yabai drawing=off \ + --set separator drawing=off \ + --set front_app drawing=off \ + --set volume_alias drawing=off \ + --set spotify.anchor drawing=off \ + --set spotify.play updates=off \ + --set brew drawing=off \ + --set divider drawing=off \ + --bar padding_left=18 +} + +zen_off() { + sketchybar --set github.bell drawing=on \ + --set apple.logo drawing=on \ + --set '/cpu.*/' drawing=on \ + --set calendar icon.drawing=on \ + --set separator drawing=on \ + --set front_app drawing=on \ + --set system.yabai drawing=on \ + --set volume_alias drawing=on \ + --set spotify.play updates=on \ + --set brew drawing=on \ + --set divider drawing=on \ + --bar padding_left=7 +} + +if [ "$1" = "on" ]; then + zen_on +elif [ "$1" = "off" ]; then + zen_off +else + if [ "$(sketchybar --query apple.logo | jq -r ".geometry.drawing")" = "on" ]; then + zen_on + else + zen_off + fi +fi + diff --git a/hosts/laptop/home.nix b/hosts/laptop/home.nix index f95fe9e..1165040 100644 --- a/hosts/laptop/home.nix +++ b/hosts/laptop/home.nix @@ -7,11 +7,14 @@ systemSettings, ... }: { - imports = [ - inputs.nixvim.homeManagerModules.nixvim - #set up nixvim - # ../../modules/nixvim - ]; + imports = + [ + inputs.nixvim.homeManagerModules.nixvim + #set up nixvim + # ../../modules/nixvim + ] + ++ lib.optionals userSettings.darwinTiling [../../modules/macos/tiling/sketchybar-home.nix]; + programs = import ../../modules/shared/homeManagerPrograms.nix {inherit inputs config pkgs lib userSettings systemSettings;}; home = { @@ -22,6 +25,14 @@ packages = pkgs.callPackage ../../modules/shared/packages.nix {inherit systemSettings;}; + # file = { + # ".config/sketchybar" = { + # source = ../../modules/macos/tiling/sketchybar; + # recursive = true; + # onChange = "${pkgs.sketchybar}/bin/sketchybar --reload"; + # }; + # }; + sessionPath = [ "$HOME/.emacs.d/bin" ]; diff --git a/modules/macos/system.nix b/modules/macos/system.nix index 9672bad..f0d75af 100644 --- a/modules/macos/system.nix +++ b/modules/macos/system.nix @@ -21,6 +21,10 @@ LSQuarantine = false; }; + WindowManager = { + EnableStandardClickToShowDesktop = false; + }; + NSGlobalDomain = { # Show extensions in finder AppleShowAllExtensions = true; diff --git a/modules/macos/tiling/aerospace.nix b/modules/macos/tiling/aerospace.nix index 0483e7a..58d0be3 100644 --- a/modules/macos/tiling/aerospace.nix +++ b/modules/macos/tiling/aerospace.nix @@ -29,7 +29,7 @@ outer = { left = 0; bottom = 0; - top = 0; + top = 40; right = 0; }; }; diff --git a/modules/macos/tiling/sketchybar-home.nix b/modules/macos/tiling/sketchybar-home.nix new file mode 100644 index 0000000..9ed4f47 --- /dev/null +++ b/modules/macos/tiling/sketchybar-home.nix @@ -0,0 +1,398 @@ +{pkgs, ...}: let + folder = "../../../files/sketchybar/"; +in { + home.file = { + sketchybarrc = { + executable = true; + target = ".config/sketchybar/sketchybarrc"; + text = '' + #!/usr/bin/env sh + + source "$HOME/.config/sketchybar/colors.sh" # Loads all defined colors + source "$HOME/.config/sketchybar/icons.sh" # Loads all defined icons + + ITEM_DIR="$HOME/.config/sketchybar/items" # Directory where the items are configured + PLUGIN_DIR="$HOME/.config/sketchybar/plugins" # Directory where all the plugin scripts are stored + + FONT="SF Pro" # Needs to have Regular, Bold, Semibold, Heavy and Black variants + PADDINGS=3 # All paddings use this value (icon, label, background) + + # Setting up and starting the helper process + HELPER=git.felix.helper + killall helper + cd $HOME/.config/sketchybar/helper && make + $HOME/.config/sketchybar/helper/helper $HELPER > /dev/null 2>&1 & + + # Unload the macOS on screen indicator overlay for volume change + # launchctl unload -F /System/Library/LaunchAgents/com.apple.OSDUIHelper.plist > /dev/null 2>&1 & + + # Setting up the general bar appearance and default values + ${pkgs.sketchybar}/bin/sketchybar --bar height=50 \ + color=$BAR_COLOR \ + shadow=off \ + position=top \ + sticky=on \ + padding_right=7 \ + padding_left=7 \ + corner_radius=12 \ + y_offset=20 \ + margin=40 \ + blur_radius=0 \ + notch_width=0 \ + --default updates=when_shown \ + icon.font="$FONT:Bold:14.0" \ + icon.color=$ICON_COLOR \ + icon.padding_left=$PADDINGS \ + icon.padding_right=$PADDINGS \ + label.font="$FONT:Semibold:13.0" \ + label.color=$LABEL_COLOR \ + label.padding_left=$PADDINGS \ + label.padding_right=$PADDINGS \ + background.padding_right=$PADDINGS \ + background.padding_left=$PADDINGS \ + background.height=26 \ + background.corner_radius=9 \ + popup.background.border_width=2 \ + popup.background.corner_radius=11 \ + popup.background.border_color=$POPUP_BORDER_COLOR \ + popup.background.color=$POPUP_BACKGROUND_COLOR \ + popup.background.shadow.drawing=on + + # Left + source "$ITEM_DIR/apple.sh" + source "$ITEM_DIR/spaces.sh" + source "$ITEM_DIR/front_app.sh" + + # Center + # source "$ITEM_DIR/spotify.sh" + source "$ITEM_DIR/calendar.sh" + + # Right + # source "$ITEM_DIR/brew.sh" + # source "$ITEM_DIR/github.sh" + source "$ITEM_DIR/volume.sh" + # source "$ITEM_DIR/divider.sh" + # source "$ITEM_DIR/cpu.sh" + + # Forcing all item scripts to run (never do this outside of sketchybarrc) + ${pkgs.sketchybar}/bin/sketchybar --update + + echo "sketchybar configuation loaded.." + ''; + }; + icons = { + executable = true; + target = ".config/sketchybar/icons.sh"; + text = builtins.readFile "${folder}/executable_icons.sh"; + }; + colors = { + executable = true; + target = ".config/sketchybar/colors.sh"; + text = '' + #!/usr/bin/env sh + # Color Palette + export BLACK=0xff4c4f69 + export WHITE=0xffeff1f5 + export RED=0xffd20f39 + export GREEN=0xff40a02b + export BLUE=0xff1e66f5 + export YELLOW=0xffdf8e1d + export ORANGE=0xfffe640b + export MAGENTA=0xffea76cb + export GREY=0xff9ca0b0 + export TRANSPARENT=0xff000000 + export BLUE2=0xff7287fd + export FLAMINGO=0xffdd7878 + + # General bar colors + export BAR_COLOR=0xeff1f5ff # Color of the bar + export ICON_COLOR=0xff4c4f69 + export LABEL_COLOR=0xff4c4f69 # Color of all labels + export BACKGROUND_1=0xffbcc0cc + export BACKGROUND_2=0xffbcc0cc + + export POPUP_BACKGROUND_COLOR=$BLACK + export POPUP_BORDER_COLOR=$WHITE + + export SHADOW_COLOR=$BLACK + ''; + }; + items_apple = { + executable = true; + target = ".config/sketchybar/items/apple.sh"; + text = builtins.readFile "${folder}/items/executable_apple.sh"; + }; + items_brew = { + executable = true; + target = ".config/sketchybar/items/brew.sh"; + text = builtins.readFile "${folder}/items/executable_brew.sh"; + }; + items_calendar = { + executable = true; + target = ".config/sketchybar/items/calendar.sh"; + text = '' + #!/usr/bin/env sh + + sketchybar --add item calendar center \ + --set calendar icon=cal \ + display=1 \ + icon.font="$FONT:Black:12.0" \ + icon.padding_right=0 \ + label.width=50 \ + label.align=right \ + background.padding_left=15 \ + update_freq=30 \ + script="$PLUGIN_DIR/calendar.sh" \ + click_script="$PLUGIN_DIR/zen.sh" + ''; + }; + items_cpu = { + executable = true; + target = ".config/sketchybar/items/cpu.sh"; + text = builtins.readFile "${folder}/items/executable_cpu.sh"; + }; + items_divider = { + executable = true; + target = ".config/sketchybar/items/divider.sh"; + text = builtins.readFile "${folder}/items/executable_divider.sh"; + }; + items_front_app = { + executable = true; + target = ".config/sketchybar/items/front_app.sh"; + text = '' + #!/usr/bin/env sh + FRONT_APP_SCRIPT='sketchybar --set $NAME label="$INFO"' + sketchybar --add event window_focus \ + --add event windows_on_spaces \ + --add item system.aerospace left \ + --set system.aerospace script="$PLUGIN_DIR/yabai.sh" \ + icon.font="$FONT:Bold:16.0" \ + label.drawing=off \ + icon.width=30 \ + icon=$YABAI_GRID \ + icon.color=$BLACK \ + updates=on \ + display=active \ + --subscribe system.aerospace window_focus \ + windows_on_spaces \ + mouse.clicked \ + --add item front_app left \ + --set front_app script="$FRONT_APP_SCRIPT" \ + icon.drawing=off \ + background.padding_left=0 \ + background.padding_right=10 \ + label.color=$BLACK \ + label.font="$FONT:Black:12.0" \ + display=active \ + --subscribe front_app front_app_switched + ''; + }; + items_github = { + executable = true; + target = ".config/sketchybar/items/github.sh"; + text = builtins.readFile "${folder}/items/executable_github.sh"; + }; + items_spaces = { + executable = true; + target = ".config/sketchybar/items/spaces.sh"; + # label.background.color=$BACKGROUND_2 + text = '' + ${pkgs.sketchybar}/bin/sketchybar --add event aerospace_workspace_change + ${pkgs.sketchybar}/bin/sketchybar --add event aerospace_mode_change + for sid in $(${pkgs.aerospace}/bin/aerospace list-workspaces --all); do + ${pkgs.sketchybar}/bin/sketchybar --add item space.$sid left \ + --subscribe space.$sid aerospace_workspace_change \ + --subscribe space.$sid aerospace_mode_change \ + --set space.$sid \ + icon=$sid \ + icon.padding_left=22 \ + icon.padding_right=22 \ + icon.highlight_color=$WHITE \ + icon.highlight=off \ + icon.color=0xff4c566a \ + background.padding_left=-8 \ + background.padding_right=-8 \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + script="$PLUGIN_DIR/aerospace.sh $sid" \ + click_script="aerospace workspace $sid" \ + label.font="JetBrainsMono Nerd Font:Regular:16.0" \ + label.padding_right=33 \ + label.background.height=26 \ + label.background.drawing=on \ + label.background.corner_radius=9 \ + label.drawing=off + done + ${pkgs.sketchybar}/bin/sketchybar --add item separator left \ + --set separator icon= \ + icon.font="JetBrainsMono Nerd Font:Regular:16.0" \ + background.padding_left=26 \ + background.padding_right=15 \ + label.drawing=off \ + display=active \ + icon.color=$GREEN + ''; + }; + items_spotify = { + executable = true; + target = ".config/sketchybar/items/spotify.sh"; + text = builtins.readFile "${folder}/items/executable_spotify.sh"; + }; + items_volume = { + executable = true; + target = ".config/sketchybar/items/volume.sh"; + text = '' + INITIAL_WIDTH=$(osascript -e 'set ovol to output volume of (get volume settings)') + ${pkgs.sketchybar}/bin/sketchybar --add item volume right \ + --subscribe volume volume_change \ + --set volume script="$PLUGIN_DIR/volume.sh" \ + updates=on \ + icon.background.drawing=on \ + icon.background.color=$FLAMINGO \ + icon.background.height=8 \ + icon.background.corner_radius=3 \ + icon.width=$INITIAL_WIDTH \ + width=100 \ + icon.align=right \ + label.drawing=off \ + background.drawing=on \ + background.color=$BACKGROUND_2 \ + background.height=8 \ + background.corner_radius=3 \ + align=left + + ${pkgs.sketchybar}/bin/sketchybar --add alias "Control Center,Sound" right \ + --rename "Control Center,Sound" volume_alias \ + --set volume_alias icon.drawing=off \ + label.drawing=off \ + alias.color=$BLUE2 \ + background.padding_right=0 \ + background.padding_left=5 \ + width=50 \ + align=right \ + click_script="$PLUGIN_DIR/volume_click.sh" + + ''; + }; + plugins_brew = { + executable = true; + target = ".config/sketchybar/plugins/brew.sh"; + text = builtins.readFile "${folder}/plugins/executable_brew.sh"; + }; + plugins_calendar = { + executable = true; + target = ".config/sketchybar/plugins/calendar.sh"; + text = builtins.readFile "${folder}/plugins/executable_calendar.sh"; + }; + plugins_github = { + executable = true; + target = ".config/sketchybar/plugins/github.sh"; + text = builtins.readFile "${folder}/plugins/executable_github.sh"; + }; + plugins_icon_map = { + executable = true; + target = ".config/sketchybar/plugins/icon_map.sh"; + text = builtins.readFile "${folder}/plugins/executable_icon_map.sh"; + }; + plugins_space = { + executable = true; + target = ".config/sketchybar/plugins/space.sh"; + text = builtins.readFile "${folder}/plugins/executable_space.sh"; + }; + plugins_spotify = { + executable = true; + target = ".config/sketchybar/plugins/spotify.sh"; + text = builtins.readFile "${folder}/plugins/executable_spotify.sh"; + }; + plugins_volume = { + executable = true; + target = ".config/sketchybar/plugins/volume.sh"; + text = '' + #!/usr/bin/env sh + WIDTH=100 + + volume_change() { + # INITIAL_WIDTH=$(${pkgs.sketchybar}/bin/sketchybar --query $NAME | ${pkgs.jq}/bin/jq ".icon.width") + # if [ "$INITIAL_WIDTH" -eq "0" ]; then + # ${pkgs.sketchybar}/bin/sketchybar --animate tanh 30 --set $NAME width=$WIDTH icon.width=$INFO + # else + # ${pkgs.sketchybar}/bin/sketchybar --set $NAME icon.width=$INFO width=$WIDTH + # fi + ${pkgs.sketchybar}/bin/sketchybar --set $NAME icon.width=$INFO + + + # sleep 5 + # FINAL_WIDTH=$(${pkgs.sketchybar}/bin/sketchybar --query $NAME | ${pkgs.jq}/bin/jq ".icon.width") + # if [ "$FINAL_WIDTH" -eq "$INFO" ]; then + # ${pkgs.sketchybar}/bin/sketchybar --animate tanh 30 --set $NAME width=0 icon.width=0 + # fi + } + + case "$SENDER" in + "volume_change") volume_change + ;; + esac + ''; + }; + plugins_volume_click = { + executable = true; + target = ".config/sketchybar/plugins/volume_click.sh"; + text = '' + #!/usr/bin/env sh + MUTED=$(osascript -e 'output muted of (get volume settings)') + if [ "$MUTED" = "false" ]; then + osascript -e 'set volume output muted true' + else + osascript -e 'set volume output muted false' + fi + ''; + }; + plugins_yabai = { + executable = true; + target = ".config/sketchybar/plugins/yabai.sh"; + text = builtins.readFile "${folder}/plugins/executable_yabai.sh"; + }; + plugins_zen = { + executable = true; + target = ".config/sketchybar/plugins/zen.sh"; + text = builtins.readFile "${folder}/plugins/executable_zen.sh"; + }; + plugins_aerospace = { + executable = true; + target = ".config/sketchybar/plugins/aerospace.sh"; + text = '' + #!/usr/bin/env bash + source "$HOME/.config/sketchybar/colors.sh" # Loads all defined colors + + highlight_focused_workspace() { + if [[ "$1" = "$FOCUSED_WORKSPACE" ]] + then + ${pkgs.sketchybar}/bin/sketchybar --animate tanh 20 --set $NAME icon.highlight=on label.width=0 + else + ${pkgs.sketchybar}/bin/sketchybar --animate tanh 20 --set $NAME icon.highlight=off label.width=dynamic + fi + } + + illuminate_mode() { + if [[ "$mode" = "service" ]] + then + ${pkgs.sketchybar}/bin/sketchybar --animate tanh 20 --set $NAME background.color=$ORANGE + elif [[ "$mode" = "resize" ]] + then + ${pkgs.sketchybar}/bin/sketchybar --animate tanh 20 --set $NAME background.color=$GREEN + else + ${pkgs.sketchybar}/bin/sketchybar --animate tanh 20 --set $NAME background.color=$BACKGROUND_1 + fi + } + case "$SENDER" in + "aerospace_workspace_change") + highlight_focused_workspace $1 + ;; + "aerospace_mode_change") + illuminate_mode + ;; + esac + ''; + }; + }; +} diff --git a/modules/macos/tiling/sketchybar.nix b/modules/macos/tiling/sketchybar.nix index 0e63acf..9716021 100644 --- a/modules/macos/tiling/sketchybar.nix +++ b/modules/macos/tiling/sketchybar.nix @@ -1,150 +1,6 @@ {pkgs, ...}: { services.sketchybar = { enable = true; - config = '' - # This is a demo config to showcase some of the most important commands. - # It is meant to be changed and configured, as it is intentionally kept sparse. - # For a (much) more advanced configuration example see my dotfiles: - # https://github.com/FelixKratz/dotfiles - - PLUGIN_DIR="$CONFIG_DIR/plugins" - - ##### Bar Appearance ##### - # Configuring the general appearance of the bar. - # These are only some of the options available. For all options see: - # https://felixkratz.github.io/SketchyBar/config/bar - # If you are looking for other colors, see the color picker: - # https://felixkratz.github.io/SketchyBar/config/tricks#color-picker - - sketchybar --bar position=top height=40 blur_radius=30 color=0x04313244 - - # Colours - SURFACE=0xff313244 - - ##### Changing Defaults ##### - # We now change some default values, which are applied to all further items. - # For a full list of all available item properties see: - # https://felixkratz.github.io/SketchyBar/config/items - - default=( - padding_left=5 - padding_right=5 - icon.font="Hack Nerd Font:Bold:17.0" - label.font="Hack Nerd Font:Bold:14.0" - icon.color=0xffcdd6f4 - label.color=0xffcdd6f4 - icon.padding_left=8 - icon.padding_right=4 - label.padding_left=4 - label.padding_right=8 - background.padding_left=2 - background.padding_right=2 - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - background.border_width=1 \ - ) - sketchybar --default "$\{default[@]}" - - sketchybar --add event aerospace_workspace_change - - for sid in $(aerospace list-workspaces --all); do - sketchybar --add item space.$sid left \ - --subscribe space.$sid aerospace_workspace_change \ - --set space.$sid \ - background.border_width=1 \ - background.border_color=0xffb4befe \ - background.corner_radius=5 \ - background.height=20 \ - icon.padding_left=0 \ - icon.padding_right=0 \ - label.padding_right=6 \ - label="$sid" \ - click_script="aerospace workspace $sid" \ - script="$CONFIG_DIR/plugins/aerospace.sh $sid" - done - - ##### Adding Left Items ##### - # We add some regular items to the left side of the bar, where - # only the properties deviating from the current defaults need to be set - - sketchybar --add item chevron left \ - --set chevron icon= label.drawing=off background.drawing=off \ - icon.color=0xfff5e0dc \ - --add item front_app left \ - --set front_app icon.drawing=off script="$PLUGIN_DIR/front_app.sh" \ - label.color=0xff94e2d5 \ - label.padding_left=8 \ - background.border_color=0xff94e2d5 \ - --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 \ - --set clock update_freq=10 icon=󰃰 script="$PLUGIN_DIR/clock.sh" \ - icon.color=0xfffab387 \ - label.color=0xffcdd6f4 \ - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - --add item volume right \ - --set volume script="$PLUGIN_DIR/volume.sh" \ - label.color=0xffcdd6f4 \ - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - --subscribe volume volume_change \ - --add item battery right \ - --set battery update_freq=120 script="$PLUGIN_DIR/battery.sh" \ - label.color=0xffcdd6f4 \ - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - --subscribe battery system_woke power_source_change - - sketchybar -m --add item mullvad right \ - --set mullvad icon= \ - icon.color=0xfff38ba8 \ - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - background.border_width=1 \ - background.border_color=0xfff38ba8 \ - label.padding_left=0 \ - label.padding_right=0 \ - icon.padding_left=6 \ - update_freq=5 \ - script="$PLUGIN_DIR/mullvad.sh" - - # Add event - sketchybar -m --add event song_update com.apple.iTunes.playerInfo - - # Add Music Item - sketchybar -m --add item music right \ - --set music script="$PLUGIN_DIR/music.sh" \ - click_script="$PLUGIN_DIR/music_click.sh" \ - label.padding_right=10 \ - label.color=0xffcdd6f4 \ - background.color=$SURFACE \ - background.corner_radius=10 \ - background.height=30 \ - background.border_width=1 \ - background.border_color=0xfff38ba8 \ - drawing=off \ - --subscribe music song_update - - ##### Force all scripts to run the first time (never do this in a script) ##### - sketchybar --update - - ''; + package = pkgs.sketchybar; }; }