diff options
45 files changed, 3298 insertions, 0 deletions
diff --git a/global/.gnupg/gpg-agent.conf b/global/.gnupg/gpg-agent.conf index c469d06..be889cc 100644 --- a/global/.gnupg/gpg-agent.conf +++ b/global/.gnupg/gpg-agent.conf @@ -1,3 +1,5 @@ allow-preset-passphrase enable-ssh-support +default-cache-ttl 86400 max-cache-ttl 86400 +pinentry-program /opt/homebrew/bin/pinentry-mac diff --git a/mac/.config/sketchybar/ 👽 aerospace-config/.aerospace.toml b/mac/.config/sketchybar/ 👽 aerospace-config/.aerospace.toml new file mode 100644 index 0000000..e42aef7 --- /dev/null +++ b/mac/.config/sketchybar/ 👽 aerospace-config/.aerospace.toml @@ -0,0 +1,256 @@ + +# It's not neceesary to copy all keys to your config. +# If the key is missing in your config, "default-config.toml" will serve as a fallback + +# You can use it to add commands that run after login to macOS user session. +# 'start-at-login' needs to be 'true' for 'after-login-command' to work +# Available commands: https://nikitabobko.github.io/AeroSpace/commands +after-login-command = [] + +# You can use it to add commands that run after AeroSpace startup. +# 'after-startup-command' is run after 'after-login-command' +# Available commands : https://nikitabobko.github.io/AeroSpace/commands +after-startup-command = [ + # JankyBorders has a built-in detection of already running process, + # so it won't be run twice on AeroSpace restart + 'exec-and-forget /opt/homebrew/opt/sketchybar/bin/sketchybar', + # 'exec-and-forget /opt/homebrew/opt/borders/bin/borders active_color="glow(0xd943ff64)" inactive_color=0x20494d64 width=8.0' +] + +exec-on-workspace-change = [ + '/bin/bash', + '-c', + '/opt/homebrew/opt/sketchybar/bin/sketchybar --trigger aerospace_workspace_change AEROSPACE_FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE AEROSPACE_PREV_WORKSPACE=$AEROSPACE_PREV_WORKSPACE', +] + +# Start AeroSpace at login +start-at-login = true + +# Normalizations. See: https://nikitabobko.github.io/AeroSpace/guide#normalization +enable-normalization-flatten-containers = false +enable-normalization-opposite-orientation-for-nested-containers = false + +# See: https://nikitabobko.github.io/AeroSpace/guide#layouts +# The 'accordion-padding' specifies the size of accordion padding +# You can set 0 to disable the padding feature +accordion-padding = 20 + +# Possible values: tiles|accordion +default-root-container-layout = 'tiles' + +# Possible values: horizontal|vertical|auto +# 'auto' means: wide monitor (anything wider than high) gets horizontal orientation, +# tall monitor (anything higher than wide) gets vertical orientation +default-root-container-orientation = 'auto' + +# Possible values: (qwerty|dvorak) +# See https://nikitabobko.github.io/AeroSpace/guide#key-mapping +key-mapping.preset = 'qwerty' + +# CURSOR CENTERING DISABLED - Keep cursor position when switching workspaces +# on-focused-monitor-changed = ['move-mouse monitor-lazy-center'] +# on-focus-changed = ['move-mouse window-lazy-center'] + +# Gaps between windows (inner-*) and between monitor edges (outer-*). +# Possible values: +# - Constant: gaps.outer.top = 8 +# - Per monitor: gaps.outer.top = [{ monitor.main = 16 }, { monitor."some-pattern" = 32 }, 24] +# In this example, 24 is a default value when there is no match. +# Monitor pattern is the same as for 'workspace-to-monitor-force-assignment'. +# See: https://nikitabobko.github.io/AeroSpace/guide#assign-workspaces-to-monitors + +[gaps] +inner.horizontal = 10 +inner.vertical = 10 +outer.top = [{ monitor."main" = 5 }, {monitor."secondary" = 40}, 5] +outer.left = 10 +outer.bottom = 10 +outer.right = 10 + +# See https://nikitabobko.github.io/AeroSpace/guide#exec-env-vars +[exec] # Again, you don't need to copy all config sections to your config. +inherit-env-vars = true # If you don't touch "exec" section, + +[exec.env-vars] # it will fallback to "default-config.toml" +PATH = '/opt/homebrew/bin:/opt/homebrew/sbin:${PATH}' + +# 'main' binding mode declaration +# See: https://nikitabobko.github.io/AeroSpace/guide#binding-modes +# 'main' binding mode must be always presented +[mode.main.binding] + +# All possible keys: +# - Letters. a, b, c, ..., z +# - Numbers. 0, 1, 2, ..., 9 +# - Keypad numbers. keypad0, keypad1, keypad2, ..., keypad9 +# - F-keys. f1, f2, ..., f20 +# - Special keys. minus, equal, period, comma, slash, backslash, quote, semicolon, backtick, +# leftSquareBracket, rightSquareBracket, space, enter, esc, backspace, tab +# - Keypad special. keypadClear, keypadDecimalMark, keypadDivide, keypadEnter, keypadEqual, +# keypadMinus, keypadMultiply, keypadPlus +# - Arrows. left, down, up, right + +# All possible modifiers: cmd, alt, ctrl, shift + +# All possible commands: https://nikitabobko.github.io/AeroSpace/commands + +# You can uncomment this line to open up terminal with alt + enter shortcut +# See: https://nikitabobko.github.io/AeroSpace/commands#exec-and-forget +# alt-enter = 'exec-and-forget open -n /System/Applications/Utilities/Terminal.app' + +# See: https://nikitabobko.github.io/AeroSpace/commands#layout +alt-slash = 'layout tiles horizontal vertical' +alt-comma = 'layout accordion horizontal vertical' + +# See: https://nikitabobko.github.io/AeroSpace/commands#focus +alt-h = 'focus left --boundaries all-monitors-outer-frame' +alt-j = 'focus down --boundaries all-monitors-outer-frame' +alt-k = 'focus up --boundaries all-monitors-outer-frame' +alt-l = 'focus right --boundaries all-monitors-outer-frame' + +# See: https://nikitabobko.github.io/AeroSpace/commands#move +alt-shift-h = 'move left' +alt-shift-j = 'move down' +alt-shift-k = 'move up' +alt-shift-l = 'move right' + +# See: https://nikitabobko.github.io/AeroSpace/commands#resize +alt-shift-minus = 'resize smart -50' +alt-shift-equal = 'resize smart +50' + +# See: https://nikitabobko.github.io/AeroSpace/commands#workspace +alt-1 = 'workspace 1' +alt-2 = 'workspace 2' +alt-3 = 'workspace 3' +alt-4 = 'workspace 4' +alt-5 = 'workspace 5' +alt-6 = 'workspace 6' +alt-7 = 'workspace 7' +alt-8 = 'workspace 8' +alt-9 = 'workspace 9' +alt-0 = 'workspace 10' +alt-t = 'workspace t' + +# See: https://nikitabobko.github.io/AeroSpace/commands#move-node-to-workspace +alt-shift-1 = ['move-node-to-workspace 1', 'workspace 1'] +alt-shift-2 = ['move-node-to-workspace 2', 'workspace 2'] +alt-shift-3 = ['move-node-to-workspace 3', 'workspace 3'] +alt-shift-4 = ['move-node-to-workspace 4', 'workspace 4'] +alt-shift-5 = ['move-node-to-workspace 5', 'workspace 5'] +alt-shift-6 = ['move-node-to-workspace 6', 'workspace 6'] +alt-shift-7 = ['move-node-to-workspace 7', 'workspace 7'] +alt-shift-8 = ['move-node-to-workspace 8', 'workspace 8'] +alt-shift-9 = ['move-node-to-workspace 9', 'workspace 9'] +alt-shift-0 = ['move-node-to-workspace 10', 'workspace 10'] +alt-shift-t = ['move-node-to-workspace t', 'workspace t'] +# See: https://nikitabobko.github.io/AeroSpace/commands#workspace-back-and-forth +alt-tab = 'workspace-back-and-forth' +# See: https://nikitabobko.github.io/AeroSpace/commands#move-workspace-to-monitor +alt-shift-tab = 'move-workspace-to-monitor --wrap-around next' + +# See: https://nikitabobko.github.io/AeroSpace/commands#mode +alt-shift-semicolon = 'mode service' + +# 'service' binding mode declaration. +# See: https://nikitabobko.github.io/AeroSpace/guide#binding-modes + +# disabled hide window +# cmd-h = [] +# rotate hangul and english + +alt-shift-f = 'fullscreen' + +[mode.service.binding] +esc = ['reload-config', 'mode main'] +r = ['flatten-workspace-tree', 'mode main'] # reset layout +#s = ['layout sticky tiling', 'mode main'] # sticky is not yet supported https://github.com/nikitabobko/AeroSpace/issues/2 +f = [ + 'layout floating tiling', + 'mode main', +] # Toggle between floating and tiling layout +alt-shift-semicolon = [ + 'fullscreen', + 'mode main', +] # Toggle between floating and tiling layout +backspace = ['close-all-windows-but-current', 'mode main'] + +alt-shift-h = ['join-with left', 'mode main'] +alt-shift-j = ['join-with down', 'mode main'] +alt-shift-k = ['join-with up', 'mode main'] +alt-shift-l = ['join-with right', 'mode main'] + +alt-shift-r = ['exec-and-forget /opt/homebrew/bin/sketchybar --reload'] + + + +# Custom window movement configuration +# ScreenStudio - set to floating to prevent window management issues +[[on-window-detected]] +if.app-id = 'com.timpler.screenstudio' +run = ['layout floating'] + +# 1. Cursor +[[on-window-detected]] +if.app-id = 'com.todesktop.230313mzl4w4u92' +run = ['move-node-to-workspace 1'] + +# 2. Chrome +[[on-window-detected]] +if.app-id = 'com.google.Chrome' +run = ['move-node-to-workspace 2'] + +# 3. Warp - split with GitHub Desktop +[[on-window-detected]] +if.app-id = 'dev.warp.Warp-Stable' +run = ['move-node-to-workspace 3'] + +# 3. GitHub Desktop - split with Warp +[[on-window-detected]] +if.app-id = 'com.github.GitHubClient' +run = ['move-node-to-workspace 3'] + +# 4. Slack +[[on-window-detected]] +if.app-id = 'com.tinyspeck.slackmacgap' +run = ['move-node-to-workspace 4'] + +# 5. ChatGPT +[[on-window-detected]] +if.app-id = 'com.openai.chat' +run = ['move-node-to-workspace 5'] + +# 6. WhatsApp +[[on-window-detected]] +if.app-id = 'net.whatsapp.WhatsApp' +run = ['move-node-to-workspace 6'] + +# 7. Finder +[[on-window-detected]] +if.app-id = 'com.apple.finder' +run = ['move-node-to-workspace 7'] + +# 8. Calendar (macOS native Calendar app) +[[on-window-detected]] +if.app-id = 'com.apple.iCal' +run = ['move-node-to-workspace 8'] + + +# Pritunl - always floating in same active window +[[on-window-detected]] +if.app-id = 'com.electron.pritunl' +run = ['layout floating'] + +# System Preferences - always floating +[[on-window-detected]] +if.app-id = 'com.apple.systempreferences' +run = ['layout floating'] + +# System Settings (macOS Ventura+) - always floating +[[on-window-detected]] +if.app-id = 'com.apple.SystemPreferences' +run = ['layout floating'] + +# Catch-all rule: move any unspecified app to workspace 10 (MUST BE LAST) +[[on-window-detected]] +run = ['move-node-to-workspace 10'] + diff --git a/mac/.config/sketchybar/LICENSE b/mac/.config/sketchybar/LICENSE new file mode 100644 index 0000000..8797b19 --- /dev/null +++ b/mac/.config/sketchybar/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Pranav Sarda + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mac/.config/sketchybar/colors.sh b/mac/.config/sketchybar/colors.sh new file mode 100755 index 0000000..bd78ee9 --- /dev/null +++ b/mac/.config/sketchybar/colors.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +### Ultra Rich Color Theme + +# Deep, saturated base colors +export BLACK=0xff101014 +export WHITE=0xfff9f9fa +export RED=0xffff5370 +export GREEN=0xffb9f27c +export BLUE=0xff82aaff +export YELLOW=0xffffcb6b +export ORANGE=0xffff966c +export MAGENTA=0xffc792ea +export CYAN=0xff89ddff +export PURPLE=0xffbb80b3 +export GREY=0xff6c7086 +export LIGHT_GREY=0xffc3c7d1 +export DARK_GREY=0xff232634 +export TRANSPARENT=0x00000000 + +# Specialized ultra-rich colors +export BATTERY_1=0xffb9f27c # Ultra Rich Green - Full +export BATTERY_2=0xffffcb6b # Ultra Rich Yellow - High +export BATTERY_3=0xffff966c # Ultra Rich Orange - Medium +export BATTERY_4=0xffff5370 # Ultra Rich Red - Low +export BATTERY_5=0xffd7263d # Ultra Deep Red - Critical + +# General bar colors +export BAR_COLOR=$TRANSPARENT # Transparent bar +export BAR_BORDER_COLOR=0xff2a2a2a # Dark grey border +export BACKGROUND_1=0xff1e1e1e # Pure dark grey background for items +export BACKGROUND_2=0xff2a2a2a # Slightly lighter dark grey for borders +export ICON_COLOR=$WHITE # Ultra white icons +export LABEL_COLOR=$WHITE # Ultra white labels +export POPUP_BACKGROUND_COLOR=0xff232634 # Ultra rich dark popup background +export POPUP_BORDER_COLOR=0xff82aaff # Ultra rich blue popup border +export SHADOW_COLOR=$BLACK # Ultra black shadows + +# Ultra rich accent colors +export ACCENT_PRIMARY=0xff82aaff # Ultra Rich Blue +export ACCENT_SECONDARY=0xffb9f27c # Ultra Rich Green +export ACCENT_TERTIARY=0xffff966c # Ultra Rich Orange +export ACCENT_QUATERNARY=0xffc792ea # Ultra Rich Purple +export ACCENT_PINK=0xffff79c6 # Ultra Rich Pink diff --git a/mac/.config/sketchybar/helper/cpu.h b/mac/.config/sketchybar/helper/cpu.h new file mode 100644 index 0000000..c350ae3 --- /dev/null +++ b/mac/.config/sketchybar/helper/cpu.h @@ -0,0 +1,122 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <mach/mach.h> +#include <stdbool.h> +#include <time.h> + +#define MAX_TOPPROC_LEN 28 + +static const char TOPPROC[] = { "/bin/ps -Aceo pid,pcpu,comm -r" }; +static const char FILTER_PATTERN[] = { "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[MAX_TOPPROC_LEN + 4]; + uint32_t caret = 0; + for (int i = 0; i < sizeof(line); i++) { + if (start && i == start - line) { + i+=9; + continue; + } + + if (caret >= MAX_TOPPROC_LEN && caret <= MAX_TOPPROC_LEN + 2) { + topproc[caret++] = '.'; + continue; + } + if (caret > MAX_TOPPROC_LEN + 2) break; + topproc[caret++] = line[i]; + if (line[i] == '\0') break; + } + + topproc[MAX_TOPPROC_LEN + 3] = '\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.top label='%s' " + "--set cpu.percent label=%.0f%% label.color=%s ", + sys_perc, + user_perc, + topproc, + total_perc*100., + color ); + } + else { + snprintf(cpu->command, 256, ""); + } + + cpu->prev_load = cpu->load; + cpu->has_prev_load = true; +} diff --git a/mac/.config/sketchybar/helper/helper b/mac/.config/sketchybar/helper/helper Binary files differnew file mode 100755 index 0000000..050cca7 --- /dev/null +++ b/mac/.config/sketchybar/helper/helper diff --git a/mac/.config/sketchybar/helper/helper.c b/mac/.config/sketchybar/helper/helper.c new file mode 100644 index 0000000..71c3038 --- /dev/null +++ b/mac/.config/sketchybar/helper/helper.c @@ -0,0 +1,31 @@ +#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(name, "cpu.percent") == 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: helper \"<bootstrap name>\"\n"); + exit(1); + } + + event_server_begin(handler, argv[1]); + return 0; +} diff --git a/mac/.config/sketchybar/helper/makefile b/mac/.config/sketchybar/helper/makefile new file mode 100644 index 0000000..ac8721a --- /dev/null +++ b/mac/.config/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/mac/.config/sketchybar/helper/sketchybar.h b/mac/.config/sketchybar/helper/sketchybar.h new file mode 100644 index 0000000..2ab4c39 --- /dev/null +++ b/mac/.config/sketchybar/helper/sketchybar.h @@ -0,0 +1,209 @@ +#pragma once + +#include <mach/mach.h> +#include <mach/mach_port.h> +#include <mach/message.h> +#include <bootstrap.h> +#include <stdlib.h> +#include <pthread.h> +#include <stdio.h> + +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; + } + + struct mach_message msg = { 0 }; + msg.header.msgh_remote_port = port; + msg.header.msgh_local_port = 0; + msg.header.msgh_id = 0; + 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 ); + + 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; + struct mach_buffer buffer; + while (mach_server->is_running) { + 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/mac/.config/sketchybar/icons.sh b/mac/.config/sketchybar/icons.sh new file mode 100755 index 0000000..bee0dad --- /dev/null +++ b/mac/.config/sketchybar/icons.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# 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= + +# Battery Icons +BATTERY_100= +BATTERY_75= +BATTERY_50= +BATTERY_25= +BATTERY_0= +BATTERY_CHARGING= + +# Volume Icons +VOLUME_100= +VOLUME_66= +VOLUME_33= +VOLUME_10= +VOLUME_0= + +# WiFi +WIFI_CONNECTED= +WIFI_DISCONNECTED= + +# svim +MODE_NORMAL= +MODE_INSERT= +MODE_VISUAL= +MODE_CMD= +MODE_PENDING= diff --git a/mac/.config/sketchybar/items/apple.sh b/mac/.config/sketchybar/items/apple.sh new file mode 100755 index 0000000..fde05b4 --- /dev/null +++ b/mac/.config/sketchybar/items/apple.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +POPUP_OFF='sketchybar --set apple.logo popup.drawing=off' +POPUP_CLICK_SCRIPT='sketchybar --set $NAME popup.drawing=toggle' + +apple_logo=( + icon=$APPLE + icon.font="$FONT:Black:16.0" + icon.color=$WHITE + padding_right=15 + label.drawing=off + click_script="$POPUP_CLICK_SCRIPT" + popup.height=35 +) + +apple_prefs=( + icon=$PREFERENCES + label="Preferences" + click_script="open -a 'System Preferences'; $POPUP_OFF" +) + +apple_activity=( + icon=$ACTIVITY + label="Activity" + click_script="open -a 'Activity Monitor'; $POPUP_OFF" +) + +apple_lock=( + icon=$LOCK + label="Lock Screen" + click_script="pmset displaysleepnow; $POPUP_OFF" +) + +sketchybar --add item apple.logo left \ + --set apple.logo "${apple_logo[@]}" \ + \ + --add item apple.prefs popup.apple.logo \ + --set apple.prefs "${apple_prefs[@]}" \ + \ + --add item apple.activity popup.apple.logo \ + --set apple.activity "${apple_activity[@]}" \ + \ + --add item apple.lock popup.apple.logo \ + --set apple.lock "${apple_lock[@]}" diff --git a/mac/.config/sketchybar/items/battery.sh b/mac/.config/sketchybar/items/battery.sh new file mode 100755 index 0000000..7955060 --- /dev/null +++ b/mac/.config/sketchybar/items/battery.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +battery=( + script="$PLUGIN_DIR/battery.sh" + icon.font="$FONT:Regular:19.0" + padding_right=3 + padding_left=0 + label.drawing=off + update_freq=120 + updates=on +) +sketchybar --add item battery right \ + --set battery "${battery[@]}"\ + icon.font.size=15 update_freq=120 script="$PLUGIN_DIR/battery.sh" \ + --subscribe battery power_source_change system_woke + diff --git a/mac/.config/sketchybar/items/calendar.sh b/mac/.config/sketchybar/items/calendar.sh new file mode 100755 index 0000000..62aadc8 --- /dev/null +++ b/mac/.config/sketchybar/items/calendar.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +calendar=( + icon= + icon.font="$FONT:Black:12.0" + icon.padding_right=0 + label.align=right + padding_left=15 + update_freq=30 + script="$PLUGIN_DIR/calendar.sh" + click_script="$PLUGIN_DIR/zen.sh" +) + +sketchybar --add item calendar right \ + --set calendar "${calendar[@]}" \ + --subscribe calendar system_woke diff --git a/mac/.config/sketchybar/items/cpu.sh b/mac/.config/sketchybar/items/cpu.sh new file mode 100755 index 0000000..249595d --- /dev/null +++ b/mac/.config/sketchybar/items/cpu.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +cpu_top=( + label.font="$FONT:Semibold:7" + label=CPU + icon.drawing=off + width=0 + padding_right=15 + y_offset=6 +) + +cpu_percent=( + label.font="$FONT:Heavy:12" + label=CPU + y_offset=-4 + padding_right=15 + width=55 + icon.drawing=off + update_freq=4 + mach_helper="$HELPER" +) + +cpu_sys=( + width=0 + graph.color=$RED + graph.fill_color=$RED + label.drawing=off + icon.drawing=off + background.height=30 + background.drawing=on + background.color=$TRANSPARENT +) + +cpu_user=( + graph.color=$BLUE + label.drawing=off + icon.drawing=off + background.height=30 + background.drawing=on + background.color=$TRANSPARENT +) + +sketchybar --add item cpu.top right \ + --set cpu.top "${cpu_top[@]}" \ + \ + --add item cpu.percent right \ + --set cpu.percent "${cpu_percent[@]}" \ + \ + --add graph cpu.sys right 75 \ + --set cpu.sys "${cpu_sys[@]}" \ + \ + --add graph cpu.user right 75 \ + --set cpu.user "${cpu_user[@]}" diff --git a/mac/.config/sketchybar/items/front_app.sh b/mac/.config/sketchybar/items/front_app.sh new file mode 100755 index 0000000..77f79ff --- /dev/null +++ b/mac/.config/sketchybar/items/front_app.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +front_app=( + label.font="$FONT:Black:12.0" + icon.background.drawing=on + display=active + script="$PLUGIN_DIR/front_app.sh" + click_script="open -a 'Mission Control'" +) +sketchybar --add item front_app left \ + --set front_app "${front_app[@]}" \ + --subscribe front_app front_app_switched + diff --git a/mac/.config/sketchybar/items/input_source.sh b/mac/.config/sketchybar/items/input_source.sh new file mode 100755 index 0000000..c72f38f --- /dev/null +++ b/mac/.config/sketchybar/items/input_source.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +sketchybar --add item input_source right +sketchybar --set input_source \ + icon.font="$FONT:Regular:20.0" \ + script="$PLUGIN_DIR/get_input_source.sh" \ + icon.color=0xffffffff \ + update_freq=1 + + diff --git a/mac/.config/sketchybar/items/spaces.sh b/mac/.config/sketchybar/items/spaces.sh new file mode 100755 index 0000000..d4284aa --- /dev/null +++ b/mac/.config/sketchybar/items/spaces.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +#SPACE_ICONS=("1" "2" "3" "4") + +# Destroy space on right click, focus space on left click. +# New space by left clicking separator (>) + +sketchybar --add event aerospace_workspace_change +#echo $(aerospace list-workspaces --monitor 1 --visible no --empty no) >> ~/aaaa + +for m in $(aerospace list-monitors | awk '{print $1}'); do + for i in $(aerospace list-workspaces --monitor $m); do + sid=$i + space=( + space="$sid" + icon="$sid" + icon.highlight_color=$RED + icon.padding_left=10 + icon.padding_right=10 + display=$m + padding_left=2 + padding_right=2 + label.padding_right=20 + label.color=$GREY + label.highlight_color=$WHITE + label.font="sketchybar-app-font:Regular:16.0" + label.y_offset=-1 + background.color=$BACKGROUND_1 + background.border_color=$BACKGROUND_2 + script="$PLUGIN_DIR/space.sh" + ) + + sketchybar --add space space.$sid left \ + --set space.$sid "${space[@]}" \ + --subscribe space.$sid mouse.clicked + + apps=$(aerospace list-windows --workspace $sid | awk -F'|' '{gsub(/^ *| *$/, "", $2); print $2}') + + icon_strip=" " + if [ "${apps}" != "" ]; then + while read -r app + do + icon_strip+=" $($CONFIG_DIR/plugins/icon_map.sh "$app")" + done <<< "${apps}" + else + icon_strip=" —" + fi + + sketchybar --set space.$sid label="$icon_strip" + done + + for i in $(aerospace list-workspaces --monitor $m --empty); do + sketchybar --set space.$i display=0 + done + +done + + +space_creator=( + icon= + icon.font="$FONT:Heavy:16.0" + padding_left=10 + padding_right=8 + label.drawing=off + display=active + #click_script='yabai -m space --create' + script="$PLUGIN_DIR/space_windows.sh" + # script="$PLUGIN_DIR/aerospace.sh" + icon.color=$WHITE +) + +# sketchybar --add item space_creator left \ +# --set space_creator "${space_creator[@]}" \ +# --subscribe space_creator space_windows_change +sketchybar --add item space_creator left \ + --set space_creator "${space_creator[@]}" \ + --subscribe space_creator aerospace_workspace_change + +# sketchybar --add item change_windows left \ +# --set change_windows script="$PLUGIN_DIR/change_windows.sh" \ +# --subscribe change_windows space_changes diff --git a/mac/.config/sketchybar/items/volume.sh b/mac/.config/sketchybar/items/volume.sh new file mode 100755 index 0000000..bc9466d --- /dev/null +++ b/mac/.config/sketchybar/items/volume.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +volume_slider=( + script="$PLUGIN_DIR/volume.sh" + updates=on + label.drawing=off + icon.drawing=off + slider.highlight_color=$BLUE + slider.background.height=5 + slider.background.corner_radius=3 + slider.background.color=$BACKGROUND_2 + slider.knob= + slider.knob.drawing=on +) + +volume_icon=( + click_script="$PLUGIN_DIR/volume_click.sh" + padding_left=10 + icon=$VOLUME_100 + icon.width=0 + icon.align=left + icon.color=$GREY + icon.font="$FONT:Regular:14.0" + label.width=25 + label.align=left + label.font="$FONT:Regular:14.0" +) + +status_bracket=( + background.color=$BACKGROUND_1 + background.border_color=$BACKGROUND_2 +) + +sketchybar --add slider volume right \ + --set volume "${volume_slider[@]}" \ + --subscribe volume volume_change \ + mouse.clicked \ + --add item volume_icon right \ + --set volume_icon "${volume_icon[@]}" + +sketchybar --add bracket status brew github.bell wifi volume_icon \ + --set status "${status_bracket[@]}" + diff --git a/mac/.config/sketchybar/items/weather.sh b/mac/.config/sketchybar/items/weather.sh new file mode 100755 index 0000000..33b08d1 --- /dev/null +++ b/mac/.config/sketchybar/items/weather.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sketchybar --add item weather right \ + --set weather \ + script="$PLUGIN_DIR/weather.sh" \ + update_freq=1500 \ + --subscribe weather mouse.clicked + diff --git a/mac/.config/sketchybar/plugins/aerospace.sh b/mac/.config/sketchybar/plugins/aerospace.sh new file mode 100755 index 0000000..b8825d5 --- /dev/null +++ b/mac/.config/sketchybar/plugins/aerospace.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +WORKSPACE_ID="$1" + +# Get currently focused workspace +FOCUSED_WORKSPACE=$(aerospace list-workspaces --focused) + +# Get workspaces for each monitor +MONITOR_1_WORKSPACES=$(aerospace list-workspaces --monitor 1) +MONITOR_2_WORKSPACES=$(aerospace list-workspaces --monitor 2) + +# Check if this workspace is on monitor 1 or 2 +ON_MONITOR_1="" +ON_MONITOR_2="" + +for ws in $MONITOR_1_WORKSPACES; do + if [ "$ws" = "$WORKSPACE_ID" ]; then + ON_MONITOR_1="true" + break + fi +done + +for ws in $MONITOR_2_WORKSPACES; do + if [ "$ws" = "$WORKSPACE_ID" ]; then + ON_MONITOR_2="true" + break + fi +done + +# Show workspace if: +# 1. It's the currently focused workspace (global focus) +# 2. OR it's one of the "representative" workspaces from each monitor +SHOULD_SHOW="false" + +if [ "$WORKSPACE_ID" = "$FOCUSED_WORKSPACE" ]; then + # Always show the currently focused workspace + SHOULD_SHOW="true" +elif [ "$ON_MONITOR_1" = "true" ] && [ "$WORKSPACE_ID" = "1" ]; then + # Show workspace 1 as representative of monitor 1 + SHOULD_SHOW="true" +elif [ "$ON_MONITOR_2" = "true" ] && [ "$WORKSPACE_ID" = "4" ]; then + # Show workspace 4 as representative of monitor 2 (adjust this number as needed) + SHOULD_SHOW="true" +fi + +if [ "$SHOULD_SHOW" = "true" ]; then + # Show the workspace item + sketchybar --set "$NAME" drawing=on + + if [ "$WORKSPACE_ID" = "$FOCUSED_WORKSPACE" ]; then + # Active workspace styling - more noticeable text + sketchybar --set "$NAME" \ + background.drawing=on \ + background.color=$BACKGROUND_2 \ + background.corner_radius=6 \ + background.height=26 \ + background.border_width=0 \ + icon.color=$WHITE \ + icon.font="SF Pro:Semibold:14.0" \ + label.color=$WHITE + else + # Workspace visible on other display but not focused - subtle styling + sketchybar --set "$NAME" \ + background.drawing=on \ + background.color=$BACKGROUND_1 \ + background.corner_radius=6 \ + background.height=26 \ + background.border_width=0 \ + icon.color=$GREY \ + icon.font="SF Pro:Medium:14.0" \ + label.color=$GREY + fi +else + # Hide workspace that's not active on any display + sketchybar --set "$NAME" drawing=off +fi + + + +# MAIN_COLOR=0xffa17fa7 +# ACCENT_COLOR=0xffe19286 +# +# echo $NAME > ~/debug_skekychybar +# +# if [ "$1" = "change-focused-window" ]; then +# echo "change-focused-window" +# focused_window_info=$(aerospace list-windows --focused) +# focused_window_id=$(echo $focused_window_info | awk -F ' \\| ' '{print $1}') +# if [ "$2" = "$focused_window_id" ]; then +# sketchybar --set $NAME icon.color=$ACCENT_COLOR +# else +# sketchybar --set $NAME icon.color=$MAIN_COLOR +# fi +# fi +# +# if [ "$1" = "change-focused-workspace" ]; then +# echo "change-focused-workspace" +# focused_workspace=$(aerospace list-workspaces --focused) +# if [ "$2" = "$focused_workspace" ]; then +# sketchybar --set $NAME label.color=$ACCENT_COLOR +# else +# sketchybar --set $NAME label.color=$MAIN_COLOR +# fi +# fi +# +# if [ "$1" = "move-window-within-workspace" ]; then +# echo "move-window-within-workspace" +# focused_workspace=$(aerospace list-workspaces --focused) +# if [ "$2" = "$focused_workspace" ]; then +# sketchybar --set $NAME label.color=$ACCENT_COLOR +# else +# sketchybar --set $NAME label.color=$MAIN_COLOR +# fi +# fi diff --git a/mac/.config/sketchybar/plugins/aerospace_display.sh b/mac/.config/sketchybar/plugins/aerospace_display.sh new file mode 100755 index 0000000..206666a --- /dev/null +++ b/mac/.config/sketchybar/plugins/aerospace_display.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get all available monitors +AVAILABLE_MONITORS=$(aerospace list-monitors) +FOCUSED_WORKSPACE=$(aerospace list-workspaces --focused) + +# Create a cache file to store last known state +CACHE_FILE="/tmp/aerospace_display_state" + +# Map aerospace monitor IDs to our logical naming +# M1 = Primary (Built-in Retina Display) = aerospace monitor 2 +# M2 = External (MAG 274UPF E2) = aerospace monitor 1 +MONITOR_M1_ID="2" # Built-in Retina Display +MONITOR_M2_ID="1" # External Monitor + +# Check which monitors are currently connected +MONITOR_M1_CONNECTED=$(echo "$AVAILABLE_MONITORS" | grep "^$MONITOR_M1_ID " | wc -l) +MONITOR_M2_CONNECTED=$(echo "$AVAILABLE_MONITORS" | grep "^$MONITOR_M2_ID " | wc -l) + +# Function to get the current workspace for a monitor +get_current_workspace_for_monitor() { + local monitor_id="$1" + local workspaces=$(aerospace list-workspaces --monitor "$monitor_id" 2>/dev/null) + + # If monitor doesn't exist, return empty + if [ -z "$workspaces" ]; then + echo "" + return + fi + + # Check if the focused workspace is on this monitor + for ws in $workspaces; do + if [ "$ws" = "$FOCUSED_WORKSPACE" ]; then + echo "$ws" + return + fi + done + + # If focused workspace is not on this monitor, return cached value or first workspace + if [ -f "$CACHE_FILE" ]; then + local cached_ws=$(grep "^$monitor_id:" "$CACHE_FILE" | cut -d: -f2) + if [ -n "$cached_ws" ]; then + # Verify the cached workspace still exists on this monitor + for ws in $workspaces; do + if [ "$ws" = "$cached_ws" ]; then + echo "$cached_ws" + return + fi + done + fi + fi + + # Fallback to first workspace on this monitor + echo "$workspaces" | head -n1 +} + +# Update cache with current state +update_cache() { + local monitor_id="$1" + local workspace="$2" + + # Create or update cache file + if [ -f "$CACHE_FILE" ]; then + # Remove old entry for this monitor + grep -v "^$monitor_id:" "$CACHE_FILE" > "$CACHE_FILE.tmp" + mv "$CACHE_FILE.tmp" "$CACHE_FILE" + fi + + # Add current entry + echo "$monitor_id:$workspace" >> "$CACHE_FILE" +} + +# Get current workspace for each monitor (if connected) +MONITOR_M1_CURRENT="" +MONITOR_M2_CURRENT="" + +if [ "$MONITOR_M1_CONNECTED" -gt 0 ]; then + MONITOR_M1_CURRENT=$(get_current_workspace_for_monitor "$MONITOR_M1_ID") + if [ -n "$MONITOR_M1_CURRENT" ]; then + update_cache "$MONITOR_M1_ID" "$MONITOR_M1_CURRENT" + fi +fi + +if [ "$MONITOR_M2_CONNECTED" -gt 0 ]; then + MONITOR_M2_CURRENT=$(get_current_workspace_for_monitor "$MONITOR_M2_ID") + if [ -n "$MONITOR_M2_CURRENT" ]; then + update_cache "$MONITOR_M2_ID" "$MONITOR_M2_CURRENT" + fi +fi + +# Handle display logic based on what's connected +if [ "$MONITOR_M1_CONNECTED" -gt 0 ] && [ "$MONITOR_M2_CONNECTED" -gt 0 ]; then + # Both monitors connected - show both + sketchybar --set monitor_1_workspace \ + icon="M1:$MONITOR_M1_CURRENT" \ + drawing=on \ + icon.width=52 \ + icon.align=center \ + icon.padding_left=4 \ + icon.padding_right=4 \ + click_script="aerospace workspace $MONITOR_M1_CURRENT" + + sketchybar --set monitor_2_workspace \ + icon="M2:$MONITOR_M2_CURRENT" \ + drawing=on \ + icon.width=52 \ + icon.align=center \ + icon.padding_left=4 \ + icon.padding_right=4 \ + click_script="aerospace workspace $MONITOR_M2_CURRENT" + + # Highlight the currently focused workspace + if [ "$MONITOR_M1_CURRENT" = "$FOCUSED_WORKSPACE" ]; then + sketchybar --set monitor_1_workspace \ + icon.color=$WHITE \ + icon.font="SF Pro:Semibold:12.0" \ + background.color=$BACKGROUND_2 + + sketchybar --set monitor_2_workspace \ + icon.color=$GREY \ + icon.font="SF Pro:Medium:12.0" \ + background.color=$BACKGROUND_1 + elif [ "$MONITOR_M2_CURRENT" = "$FOCUSED_WORKSPACE" ]; then + sketchybar --set monitor_2_workspace \ + icon.color=$WHITE \ + icon.font="SF Pro:Semibold:12.0" \ + background.color=$BACKGROUND_2 + + sketchybar --set monitor_1_workspace \ + icon.color=$GREY \ + icon.font="SF Pro:Medium:12.0" \ + background.color=$BACKGROUND_1 + else + # Neither monitor has focus, show both as inactive + sketchybar --set monitor_1_workspace \ + icon.color=$GREY \ + icon.font="SF Pro:Medium:12.0" \ + background.color=$BACKGROUND_1 + + sketchybar --set monitor_2_workspace \ + icon.color=$GREY \ + icon.font="SF Pro:Medium:12.0" \ + background.color=$BACKGROUND_1 + fi + +elif [ "$MONITOR_M1_CONNECTED" -gt 0 ]; then + # Only M1 (primary) connected - show just the workspace number + sketchybar --set monitor_1_workspace \ + icon="$MONITOR_M1_CURRENT" \ + drawing=on \ + icon.color=$WHITE \ + icon.font="SF Pro:Semibold:14.0" \ + icon.width=32 \ + icon.align=center \ + icon.padding_left=4 \ + icon.padding_right=4 \ + background.color=$BACKGROUND_2 \ + click_script="aerospace workspace $MONITOR_M1_CURRENT" + + sketchybar --set monitor_2_workspace drawing=off + +elif [ "$MONITOR_M2_CONNECTED" -gt 0 ]; then + # Only M2 (external) connected - show just the workspace number + sketchybar --set monitor_2_workspace \ + icon="$MONITOR_M2_CURRENT" \ + drawing=on \ + icon.color=$WHITE \ + icon.font="SF Pro:Semibold:14.0" \ + icon.width=32 \ + icon.align=center \ + icon.padding_left=4 \ + icon.padding_right=4 \ + background.color=$BACKGROUND_2 \ + click_script="aerospace workspace $MONITOR_M2_CURRENT" + + sketchybar --set monitor_1_workspace drawing=off + +else + # No monitors detected - hide both (shouldn't happen) + sketchybar --set monitor_1_workspace drawing=off + sketchybar --set monitor_2_workspace drawing=off +fi
\ No newline at end of file diff --git a/mac/.config/sketchybar/plugins/apple.sh b/mac/.config/sketchybar/plugins/apple.sh new file mode 100755 index 0000000..8a22606 --- /dev/null +++ b/mac/.config/sketchybar/plugins/apple.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Create a simple popup menu for the Apple logo +sketchybar --set apple.logo popup.drawing=toggle + +# Check if popup is being shown +if [ "$(sketchybar --query apple.logo | jq -r '.popup.drawing')" = "on" ]; then + # Add popup items + sketchybar --add item apple.prefs popup.apple.logo \ + --set apple.prefs icon="" \ + icon.color=$BLUE \ + label="System Preferences" \ + click_script="open /System/Applications/System\ Preferences.app; sketchybar --set apple.logo popup.drawing=off" + + sketchybar --add item apple.activity popup.apple.logo \ + --set apple.activity icon="" \ + icon.color=$GREEN \ + label="Activity Monitor" \ + click_script="open /System/Applications/Utilities/Activity\ Monitor.app; sketchybar --set apple.logo popup.drawing=off" + + sketchybar --add item apple.lock popup.apple.logo \ + --set apple.lock icon="" \ + icon.color=$RED \ + label="Lock Screen" \ + click_script="pmset displaysleepnow; sketchybar --set apple.logo popup.drawing=off" + + sketchybar --add item apple.sleep popup.apple.logo \ + --set apple.sleep icon="" \ + icon.color=$YELLOW \ + label="Sleep" \ + click_script="pmset sleepnow; sketchybar --set apple.logo popup.drawing=off" +else + # Remove popup items when hiding + sketchybar --remove apple.prefs apple.activity apple.lock apple.sleep +fi diff --git a/mac/.config/sketchybar/plugins/battery.sh b/mac/.config/sketchybar/plugins/battery.sh new file mode 100755 index 0000000..72535e2 --- /dev/null +++ b/mac/.config/sketchybar/plugins/battery.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get battery information +BATTERY_INFO=$(pmset -g batt | grep -Eo "[0-9]+%" | cut -d% -f1) +POWER_SOURCE=$(pmset -g ps | head -1) + +# Check if charging +if [[ $POWER_SOURCE == *"AC Power"* ]]; then + CHARGING=true +else + CHARGING=false +fi + +# Set battery level +BATTERY_LEVEL=$BATTERY_INFO + +# Determine icon and color based on battery level and charging status +if [[ $CHARGING == true ]]; then + ICON="" # Charging icon + COLOR=$ACCENT_SECONDARY +else + if [[ $BATTERY_LEVEL -gt 75 ]]; then + ICON="" # Full battery + COLOR=$BATTERY_1 + elif [[ $BATTERY_LEVEL -gt 50 ]]; then + ICON="" # Three quarters + COLOR=$BATTERY_2 + elif [[ $BATTERY_LEVEL -gt 25 ]]; then + ICON="" # Half battery + COLOR=$BATTERY_3 + elif [[ $BATTERY_LEVEL -gt 10 ]]; then + ICON="" # Quarter battery + COLOR=$BATTERY_4 + else + ICON="" # Empty battery + COLOR=$BATTERY_5 + fi +fi + +# Update the battery item +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label="$BATTERY_LEVEL%" \ + label.color=$WHITE \ + label.font="SF Pro:Medium:13.0" diff --git a/mac/.config/sketchybar/plugins/bluetooth.sh b/mac/.config/sketchybar/plugins/bluetooth.sh new file mode 100755 index 0000000..d8dd1b6 --- /dev/null +++ b/mac/.config/sketchybar/plugins/bluetooth.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Multiple methods to detect Bluetooth status +BT_ENABLED=false +AIRPODS_CONNECTED=false + +# Method 1: Check using defaults (most reliable) +BT_STATE=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null) +if [[ "$BT_STATE" == "1" ]]; then + BT_ENABLED=true +fi + +# Method 2: Check using system_profiler with better parsing +if [[ "$BT_ENABLED" == false ]]; then + BT_POWER=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -i "state" | grep -i "on") + if [[ -n "$BT_POWER" ]]; then + BT_ENABLED=true + fi +fi + +# Method 3: Check if blueutil is available and use it (most accurate) +if command -v blueutil &> /dev/null; then + BT_UTIL_STATE=$(blueutil -p 2>/dev/null) + if [[ "$BT_UTIL_STATE" == "1" ]]; then + BT_ENABLED=true + elif [[ "$BT_UTIL_STATE" == "0" ]]; then + BT_ENABLED=false + fi +fi + +# Method 4: Check if any Bluetooth devices are connected as fallback +if [[ "$BT_ENABLED" == false ]]; then + BT_DEVICES=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -i "connected: yes") + if [[ -n "$BT_DEVICES" ]]; then + BT_ENABLED=true + fi +fi + +# Check specifically for AirPods connection +if [[ "$BT_ENABLED" == true ]]; then + # Method 1: Check for AirPods in connected devices (SPBluetoothDataType) + AIRPODS_CHECK=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -i -A 10 -B 2 "airpods\|air pods") + if [[ -n "$AIRPODS_CHECK" ]]; then + # Check if AirPods are actually connected (not just paired) + AIRPODS_CONNECTED_CHECK=$(echo "$AIRPODS_CHECK" | grep -i "connected: yes") + if [[ -n "$AIRPODS_CONNECTED_CHECK" ]]; then + AIRPODS_CONNECTED=true + fi + fi + + # Method 2: Check if AirPods are active audio device (more reliable) + if [[ "$AIRPODS_CONNECTED" == false ]]; then + AIRPODS_AUDIO_CHECK=$(system_profiler SPAudioDataType 2>/dev/null | grep -i -A 5 -B 5 "airpods") + if [[ -n "$AIRPODS_AUDIO_CHECK" ]]; then + # Check if AirPods are set as default output device + AIRPODS_DEFAULT_OUTPUT=$(echo "$AIRPODS_AUDIO_CHECK" | grep -i "default output device: yes") + if [[ -n "$AIRPODS_DEFAULT_OUTPUT" ]]; then + AIRPODS_CONNECTED=true + fi + fi + fi + + # Method 3: Alternative check using blueutil if available + if [[ "$AIRPODS_CONNECTED" == false ]] && command -v blueutil &> /dev/null; then + CONNECTED_DEVICES=$(blueutil --connected 2>/dev/null) + if [[ "$CONNECTED_DEVICES" == *"AirPods"* ]] || [[ "$CONNECTED_DEVICES" == *"Air Pods"* ]]; then + AIRPODS_CONNECTED=true + fi + fi +fi + +# Set icon and color based on connection status +if [[ "$AIRPODS_CONNECTED" == true ]]; then + # AirPods connected - AirPods icon in white + ICON="" + COLOR=$ACCENT_PINK +elif [[ "$BT_ENABLED" == true ]]; then + # Bluetooth enabled but no AirPods - blue Bluetooth icon + ICON="" + COLOR=$ACCENT_PRIMARY # Blue +else + # Bluetooth disabled - gray icon + ICON="" + COLOR=$GREY +fi + +# Update the Bluetooth item - icon only, no label +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label.drawing=off
\ No newline at end of file diff --git a/mac/.config/sketchybar/plugins/calendar.sh b/mac/.config/sketchybar/plugins/calendar.sh new file mode 100755 index 0000000..013e3db --- /dev/null +++ b/mac/.config/sketchybar/plugins/calendar.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get next calendar event +get_next_event() { + # Use EventKit to get calendar events + local event_info=$(osascript << 'EOF' +tell application "Calendar" + set currentDate to current date + set endOfDay to currentDate + (1 * days) + + set allEvents to {} + repeat with cal in calendars + set calEvents to (events of cal whose start date ≥ currentDate and start date ≤ endOfDay) + set allEvents to allEvents & calEvents + end repeat + + if (count of allEvents) > 0 then + set nextEvent to item 1 of allEvents + set eventStart to start date of nextEvent + set eventTitle to summary of nextEvent + + # Find the earliest upcoming event + repeat with evt in allEvents + if start date of evt < eventStart and start date of evt ≥ currentDate then + set nextEvent to evt + set eventStart to start date of evt + set eventTitle to summary of evt + end if + end repeat + + # Format the time properly + set eventHour to hours of eventStart + set eventMinute to minutes of eventStart + + # Convert to 12-hour format + if eventHour = 0 then + set displayHour to 12 + set ampm to "AM" + else if eventHour < 12 then + set displayHour to eventHour + set ampm to "AM" + else if eventHour = 12 then + set displayHour to 12 + set ampm to "PM" + else + set displayHour to eventHour - 12 + set ampm to "PM" + end if + + # Format minutes with leading zero if needed + if eventMinute < 10 then + set minuteStr to "0" & eventMinute + else + set minuteStr to eventMinute as string + end if + + set formattedTime to displayHour & ":" & minuteStr & " " & ampm + + set eventDate to date string of eventStart + set todayDate to date string of currentDate + + if eventDate = todayDate then + return eventTitle & "|" & formattedTime + else + return eventTitle & "|Tomorrow " & formattedTime + end if + else + return "No events" + end if +end tell +EOF +) + + echo "$event_info" +} + +# Get calendar information +EVENT_INFO=$(get_next_event 2>/dev/null) + +if [[ "$EVENT_INFO" == "No events" ]] || [[ -z "$EVENT_INFO" ]]; then + # No upcoming events + ICON="" + COLOR=$GREY + LABEL="No Events" +else + # Parse event information + IFS='|' read -r event_title event_time <<< "$EVENT_INFO" + + # Set icon and color based on time + if [[ "$event_time" == "Tomorrow"* ]]; then + ICON="" + COLOR=$ACCENT_QUATERNARY + else + ICON="" + COLOR=$ACCENT_PRIMARY + fi + + # Truncate long event titles + if [[ ${#event_title} -gt 15 ]]; then + event_title="${event_title:0:15}..." + fi + + # Create multi-line label using actual newline + LABEL="$event_title +$event_time" +fi + +# Update the Calendar item +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label="$LABEL" \ + label.color=$WHITE \ + label.font="SF Pro:Medium:12.0" \ + label.max_chars=20 diff --git a/mac/.config/sketchybar/plugins/change_windows.sh b/mac/.config/sketchybar/plugins/change_windows.sh new file mode 100755 index 0000000..69364b8 --- /dev/null +++ b/mac/.config/sketchybar/plugins/change_windows.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo change_windows.sh NAME: $NAME, SENDER: $SENDER >> ~/aaaa diff --git a/mac/.config/sketchybar/plugins/clock.sh b/mac/.config/sketchybar/plugins/clock.sh new file mode 100755 index 0000000..f93c806 --- /dev/null +++ b/mac/.config/sketchybar/plugins/clock.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get current time and date +TIME=$(date "+%I:%M %p") +DATE=$(date "+%a %d %b") + +# Format the label with both time and date +LABEL="$TIME $DATE" + +# Set the clock with enhanced styling +sketchybar --set "$NAME" label="$LABEL" \ + icon="" \ + icon.color=$YELLOW \ + label.color=$WHITE \ + label.font="SF Pro:Medium:13.0" + diff --git a/mac/.config/sketchybar/plugins/clock_click.sh b/mac/.config/sketchybar/plugins/clock_click.sh new file mode 100755 index 0000000..e2419ad --- /dev/null +++ b/mac/.config/sketchybar/plugins/clock_click.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Create a popup showing calendar and date info +sketchybar --set clock popup.drawing=toggle + +# Check if popup is being shown +if [ "$(sketchybar --query clock | jq -r '.popup.drawing')" = "on" ]; then + # Get current date info + FULL_DATE=$(date "+%A, %B %d, %Y") + WEEK_NUMBER=$(date "+Week %V") + DAY_OF_YEAR=$(date "+Day %j of %Y") + + # Add date information items + sketchybar --add item clock.full_date popup.clock \ + --set clock.full_date icon="" \ + icon.color=$YELLOW \ + label="$FULL_DATE" \ + click_script="open /System/Applications/Calendar.app; sketchybar --set clock popup.drawing=off" + + sketchybar --add item clock.week popup.clock \ + --set clock.week icon="" \ + icon.color=$BLUE \ + label="$WEEK_NUMBER" \ + click_script="sketchybar --set clock popup.drawing=off" + + sketchybar --add item clock.day_of_year popup.clock \ + --set clock.day_of_year icon="" \ + icon.color=$GREEN \ + label="$DAY_OF_YEAR" \ + click_script="sketchybar --set clock popup.drawing=off" + + sketchybar --add item clock.calendar popup.clock \ + --set clock.calendar icon="" \ + icon.color=$ORANGE \ + label="Open Calendar" \ + click_script="open /System/Applications/Calendar.app; sketchybar --set clock popup.drawing=off" +else + # Remove popup items when hiding + sketchybar --remove clock.full_date clock.week clock.day_of_year clock.calendar +fi
\ No newline at end of file diff --git a/mac/.config/sketchybar/plugins/cpu.sh b/mac/.config/sketchybar/plugins/cpu.sh new file mode 100755 index 0000000..dd55b0a --- /dev/null +++ b/mac/.config/sketchybar/plugins/cpu.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get CPU usage percentage +CPU_USAGE=$(top -l 1 -n 0 | grep "CPU usage" | awk '{print $3}' | sed 's/%//') + +# Handle empty CPU usage +if [[ -z "$CPU_USAGE" ]]; then + CPU_USAGE=0 +fi + +# Remove decimal point for comparison +CPU_INT=${CPU_USAGE%.*} + +# Set icon and color based on CPU usage +if [[ $CPU_INT -le 25 ]]; then + ICON="" # Low CPU + COLOR=$ACCENT_SECONDARY # Green +elif [[ $CPU_INT -le 50 ]]; then + ICON="" # Medium CPU + COLOR=$ACCENT_PRIMARY # Blue +elif [[ $CPU_INT -le 75 ]]; then + ICON="" # High CPU + COLOR=$ACCENT_TERTIARY # Orange +else + ICON="" # Very High CPU + COLOR=$RED # Red +fi + +# Update the CPU item +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label="$CPU_USAGE%" \ + label.color=$WHITE \ + label.font="SF Pro:Medium:12.0" diff --git a/mac/.config/sketchybar/plugins/front_app.sh b/mac/.config/sketchybar/plugins/front_app.sh new file mode 100755 index 0000000..fcae89d --- /dev/null +++ b/mac/.config/sketchybar/plugins/front_app.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash + +# Source colors and icons for consistent theming +source "$CONFIG_DIR/colors.sh" +source "$CONFIG_DIR/icons.sh" + +# Get the current application +if [ "$SENDER" = "front_app_switched" ]; then + APP_NAME="$INFO" +else + APP_NAME=$(yabai -m query --windows --window | jq -r '.app' 2>/dev/null || echo "$(osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true')") +fi + +# Icon mapping for common applications +case $APP_NAME in + "Cursor") + ICON="" + ;; + "Visual Studio Code") + ICON="" + ;; + "Slack") + ICON="" + ;; + "Discord") + ICON="" + ;; + "Google Chrome") + ICON="" + ;; + "Safari") + ICON="" + ;; + "Firefox") + ICON="" + ;; + "Terminal") + ICON="" + ;; + "iTerm2") + ICON="" + ;; + "Finder") + ICON="" + ;; + "Spotify") + ICON="" + ;; + "Music") + ICON="" + ;; + "Mail") + ICON="" + ;; + "Messages") + ICON="" + ;; + "FaceTime") + ICON="" + ;; + "Zoom") + ICON="" + ;; + "Notion") + ICON="" + ;; + "Obsidian") + ICON="" + ;; + "Xcode") + ICON="" + ;; + "Docker") + ICON="" + ;; + "Figma") + ICON="" + ;; + "Sketch") + ICON="" + ;; + "Photoshop") + ICON="" + ;; + "System Preferences") + ICON="" + ;; + "System Settings") + ICON="" + ;; + "Activity Monitor") + ICON="" + ;; + *) + # Default icon for unknown applications + ICON="" + ;; +esac + +# Update the front_app item +sketchybar --set "$NAME" icon="$ICON" \ + icon.color=$ACCENT_QUATERNARY \ + label="$APP_NAME" \ + label.color=$WHITE diff --git a/mac/.config/sketchybar/plugins/get_input_source.sh b/mac/.config/sketchybar/plugins/get_input_source.sh new file mode 100755 index 0000000..89dab2b --- /dev/null +++ b/mac/.config/sketchybar/plugins/get_input_source.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# hangul and english item + +# Read the plist data +plist_data=$(defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources) +current_input_source=$(echo "$plist_data" | plutil -convert xml1 -o - - | grep -A1 'KeyboardLayout Name' | tail -n1 | cut -d '>' -f2 | cut -d '<' -f1) + +if [ "$current_input_source" = "ABC" ]; then + sketchybar --set input_source icon="" +else + sketchybar --set input_source icon="" +fi diff --git a/mac/.config/sketchybar/plugins/icon_map.sh b/mac/.config/sketchybar/plugins/icon_map.sh new file mode 100755 index 0000000..e23f8d0 --- /dev/null +++ b/mac/.config/sketchybar/plugins/icon_map.sh @@ -0,0 +1,637 @@ +#!/usr/bin/env bash + +### START-OF-ICON-MAP +function __icon_map() { + case "$1" in + "Live") + icon_result=":ableton:" + ;; + "Adobe Bridge"*) + icon_result=":adobe_bridge:" + ;; + "Affinity Designer") + icon_result=":affinity_designer:" + ;; + "Affinity Designer 2") + icon_result=":affinity_designer_2:" + ;; + "Affinity Photo") + icon_result=":affinity_photo:" + ;; + "Affinity Photo 2") + icon_result=":affinity_photo_2:" + ;; + "Affinity Publisher") + icon_result=":affinity_publisher:" + ;; + "Affinity Publisher 2") + icon_result=":affinity_publisher_2:" + ;; + "Airmail") + icon_result=":airmail:" + ;; + "Alacritty") + icon_result=":alacritty:" + ;; + "Alfred") + icon_result=":alfred:" + ;; + "Android Messages") + icon_result=":android_messages:" + ;; + "Android Studio") + icon_result=":android_studio:" + ;; + "Anytype") + icon_result=":anytype:" + ;; + "App Eraser") + icon_result=":app_eraser:" + ;; + "App Store") + icon_result=":app_store:" + ;; + "Arc") + icon_result=":arc:" + ;; + "Atom") + icon_result=":atom:" + ;; + "Audacity") + icon_result=":audacity:" + ;; + "Bambu Studio") + icon_result=":bambu_studio:" + ;; + "MoneyMoney") + icon_result=":bank:" + ;; + "Battle.net") + icon_result=":battle_net:" + ;; + "Bear") + icon_result=":bear:" + ;; + "BetterTouchTool") + icon_result=":bettertouchtool:" + ;; + "Bilibili" | "哔哩哔哩") + icon_result=":bilibili:" + ;; + "Bitwarden") + icon_result=":bit_warden:" + ;; + "Blender") + icon_result=":blender:" + ;; + "BluOS Controller") + icon_result=":bluos_controller:" + ;; + "Calibre") + icon_result=":book:" + ;; + "Brave Browser") + icon_result=":brave_browser:" + ;; + "Calculator" | "Calculette") + icon_result=":calculator:" + ;; + "Calendar" | "日历" | "Fantastical" | "Cron" | "Amie" | "Calendrier" | "Notion Calendar") + icon_result=":calendar:" + ;; + "Caprine") + icon_result=":caprine:" + ;; + "Citrix Workspace" | "Citrix Viewer") + icon_result=":citrix:" + ;; + "ClickUp") + icon_result=":click_up:" + ;; + "Code" | "Code - Insiders") + icon_result=":code:" + ;; + "Color Picker" | "数码测色计") + icon_result=":color_picker:" + ;; + "CotEditor") + icon_result=":coteditor:" + ;; + "Creative Cloud") + icon_result=":creative_cloud:" + ;; + "Cypress") + icon_result=":cypress:" + ;; + "DataGrip") + icon_result=":datagrip:" + ;; + "DataSpell") + icon_result=":dataspell:" + ;; + "DaVinci Resolve") + icon_result=":davinciresolve:" + ;; + "Default") + icon_result=":default:" + ;; + "CleanMyMac X") + icon_result=":desktop:" + ;; + "DEVONthink 3") + icon_result=":devonthink3:" + ;; + "DingTalk" | "钉钉" | "阿里钉") + icon_result=":dingtalk:" + ;; + "Discord" | "Discord Canary" | "Discord PTB") + icon_result=":discord:" + ;; + "Docker" | "Docker Desktop") + icon_result=":docker:" + ;; + "GrandTotal" | "Receipts") + icon_result=":dollar:" + ;; + "Double Commander") + icon_result=":doublecmd:" + ;; + "Drafts") + icon_result=":drafts:" + ;; + "Dropbox") + icon_result=":dropbox:" + ;; + "Element") + icon_result=":element:" + ;; + "Emacs") + icon_result=":emacs:" + ;; + "Evernote Legacy") + icon_result=":evernote_legacy:" + ;; + "FaceTime" | "FaceTime 通话") + icon_result=":face_time:" + ;; + "Figma") + icon_result=":figma:" + ;; + "Final Cut Pro") + icon_result=":final_cut_pro:" + ;; + "Finder" | "访达") + icon_result=":finder:" + ;; + "Firefox") + icon_result=":firefox:" + ;; + "Firefox Developer Edition" | "Firefox Nightly") + icon_result=":firefox_developer_edition:" + ;; + "Folx") + icon_result=":folx:" + ;; + "Fusion") + icon_result=":fusion:" + ;; + "System Preferences" | "System Settings" | "系统设置" | "Réglages Système") + icon_result=":gear:" + ;; + "GitHub Desktop") + icon_result=":git_hub:" + ;; + "Godot") + icon_result=":godot:" + ;; + "GoLand") + icon_result=":goland:" + ;; + "Chromium" | "Google Chrome" | "Google Chrome Canary") + icon_result=":google_chrome:" + ;; + "Grammarly Editor") + icon_result=":grammarly:" + ;; + "Home Assistant") + icon_result=":home_assistant:" + ;; + "Hyper") + icon_result=":hyper:" + ;; + "IntelliJ IDEA") + icon_result=":idea:" + ;; + "Inkdrop") + icon_result=":inkdrop:" + ;; + "Inkscape") + icon_result=":inkscape:" + ;; + "Insomnia") + icon_result=":insomnia:" + ;; + "Iris") + icon_result=":iris:" + ;; + "iTerm" | "iTerm2") + icon_result=":iterm:" + ;; + "Jellyfin Media Player") + icon_result=":jellyfin:" + ;; + "Joplin") + icon_result=":joplin:" + ;; + "카카오톡" | "KakaoTalk") + icon_result=":kakaotalk:" + ;; + "Kakoune") + icon_result=":kakoune:" + ;; + "KeePassXC") + icon_result=":kee_pass_x_c:" + ;; + "Keyboard Maestro") + icon_result=":keyboard_maestro:" + ;; + "Keynote" | "Keynote 讲演") + icon_result=":keynote:" + ;; + "kitty") + icon_result=":kitty:" + ;; + "League of Legends") + icon_result=":league_of_legends:" + ;; + "LibreWolf") + icon_result=":libre_wolf:" + ;; + "Adobe Lightroom") + icon_result=":lightroom:" + ;; + "Lightroom Classic") + icon_result=":lightroomclassic:" + ;; + "LINE") + icon_result=":line:" + ;; + "Linear") + icon_result=":linear:" + ;; + "LM Studio") + icon_result=":lm_studio:" + ;; + "LocalSend") + icon_result=":localsend:" + ;; + "Logic Pro") + icon_result=":logicpro:" + ;; + "Logseq") + icon_result=":logseq:" + ;; + "Canary Mail" | "HEY" | "Mail" | "Mailspring" | "MailMate" | "Superhuman" | "Spark" | "邮件") + icon_result=":mail:" + ;; + "MAMP" | "MAMP PRO") + icon_result=":mamp:" + ;; + "Maps" | "Google Maps") + icon_result=":maps:" + ;; + "Matlab") + icon_result=":matlab:" + ;; + "Mattermost") + icon_result=":mattermost:" + ;; + "Messages" | "信息" | "Nachrichten") + icon_result=":messages:" + ;; + "Messenger") + icon_result=":messenger:" + ;; + "Microsoft Edge") + icon_result=":microsoft_edge:" + ;; + "Microsoft Excel") + icon_result=":microsoft_excel:" + ;; + "Microsoft Outlook") + icon_result=":microsoft_outlook:" + ;; + "Microsoft PowerPoint") + icon_result=":microsoft_power_point:" + ;; + "Microsoft Remote Desktop") + icon_result=":microsoft_remote_desktop:" + ;; + "Microsoft Teams" | "Microsoft Teams (work or school)") + icon_result=":microsoft_teams:" + ;; + "Microsoft Word") + icon_result=":microsoft_word:" + ;; + "Min") + icon_result=":min_browser:" + ;; + "Miro") + icon_result=":miro:" + ;; + "MongoDB Compass"*) + icon_result=":mongodb:" + ;; + "mpv") + icon_result=":mpv:" + ;; + "Mullvad Browser") + icon_result=":mullvad_browser:" + ;; + "Music" | "音乐" | "Musique") + icon_result=":music:" + ;; + "Neovide" | "neovide") + icon_result=":neovide:" + ;; + "Neovim" | "neovim" | "nvim") + icon_result=":neovim:" + ;; + "网易云音乐") + icon_result=":netease_music:" + ;; + "Noodl" | "Noodl Editor") + icon_result=":noodl:" + ;; + "NordVPN") + icon_result=":nord_vpn:" + ;; + "Notability") + icon_result=":notability:" + ;; + "Notes" | "备忘录") + icon_result=":notes:" + ;; + "Notion") + icon_result=":notion:" + ;; + "Nova") + icon_result=":nova:" + ;; + "Numbers" | "Numbers 表格") + icon_result=":numbers:" + ;; + "Obsidian") + icon_result=":obsidian:" + ;; + "OBS") + icon_result=":obsstudio:" + ;; + "OmniFocus") + icon_result=":omni_focus:" + ;; + "1Password") + icon_result=":one_password:" + ;; + "ChatGPT") + icon_result=":openai:" + ;; + "OpenVPN Connect") + icon_result=":openvpn_connect:" + ;; + "Opera") + icon_result=":opera:" + ;; + "OrcaSlicer") + icon_result=":orcaslicer:" + ;; + "Orion" | "Orion RC") + icon_result=":orion:" + ;; + "Pages" | "Pages 文稿") + icon_result=":pages:" + ;; + "Parallels Desktop") + icon_result=":parallels:" + ;; + "Parsec") + icon_result=":parsec:" + ;; + "Preview" | "预览" | "Skim" | "zathura" | "Aperçu") + icon_result=":pdf:" + ;; + "PDF Expert") + icon_result=":pdf_expert:" + ;; + "Adobe Photoshop"*) + icon_result=":photoshop:" + ;; + "PhpStorm") + icon_result=":php_storm:" + ;; + "Pi-hole Remote") + icon_result=":pihole:" + ;; + "Pine") + icon_result=":pine:" + ;; + "Podcasts" | "播客") + icon_result=":podcasts:" + ;; + "PomoDone App") + icon_result=":pomodone:" + ;; + "Postman") + icon_result=":postman:" + ;; + "Proton Mail" | "Proton Mail Bridge") + icon_result=":proton_mail:" + ;; + "PrusaSlicer" | "SuperSlicer") + icon_result=":prusaslicer:" + ;; + "PyCharm") + icon_result=":pycharm:" + ;; + "QQ") + icon_result=":qq:" + ;; + "QQ音乐" | "QQMusic") + icon_result=":qqmusic:" + ;; + "Quantumult X") + icon_result=":quantumult_x:" + ;; + "qutebrowser") + icon_result=":qute_browser:" + ;; + "Raindrop.io") + icon_result=":raindrop_io:" + ;; + "Reeder") + icon_result=":reeder5:" + ;; + "Reminders" | "提醒事项" | "Rappels") + icon_result=":reminders:" + ;; + "Replit") + icon_result=":replit:" + ;; + "Rider" | "JetBrains Rider") + icon_result=":rider:" + ;; + "Safari" | "Safari浏览器" | "Safari Technology Preview") + icon_result=":safari:" + ;; + "Sequel Ace") + icon_result=":sequel_ace:" + ;; + "Sequel Pro") + icon_result=":sequel_pro:" + ;; + "Setapp") + icon_result=":setapp:" + ;; + "SF Symbols") + icon_result=":sf_symbols:" + ;; + "Signal") + icon_result=":signal:" + ;; + "Sketch") + icon_result=":sketch:" + ;; + "Skype") + icon_result=":skype:" + ;; + "Slack") + icon_result=":slack:" + ;; + "Spark Desktop") + icon_result=":spark:" + ;; + "Spotify") + icon_result=":spotify:" + ;; + "Spotlight") + icon_result=":spotlight:" + ;; + "Sublime Text") + icon_result=":sublime_text:" + ;; + "Tana") + icon_result=":tana:" + ;; + "TeamSpeak 3") + icon_result=":team_speak:" + ;; + "Telegram") + icon_result=":telegram:" + ;; + "Terminal" | "终端") + icon_result=":terminal:" + ;; + "Typora") + icon_result=":text:" + ;; + "Microsoft To Do" | "Things") + icon_result=":things:" + ;; + "Thunderbird") + icon_result=":thunderbird:" + ;; + "TickTick") + icon_result=":tick_tick:" + ;; + "TIDAL") + icon_result=":tidal:" + ;; + "Tiny RDM") + icon_result=":tinyrdm:" + ;; + "Todoist") + icon_result=":todoist:" + ;; + "Toggl Track") + icon_result=":toggl_track:" + ;; + "Tor Browser") + icon_result=":tor_browser:" + ;; + "Tower") + icon_result=":tower:" + ;; + "Transmit") + icon_result=":transmit:" + ;; + "Trello") + icon_result=":trello:" + ;; + "Tweetbot" | "Twitter") + icon_result=":twitter:" + ;; + "MacVim" | "Vim" | "VimR") + icon_result=":vim:" + ;; + "Vivaldi") + icon_result=":vivaldi:" + ;; + "VLC") + icon_result=":vlc:" + ;; + "VMware Fusion") + icon_result=":vmware_fusion:" + ;; + "VSCodium") + icon_result=":vscodium:" + ;; + "Warp") + icon_result=":warp:" + ;; + "WebStorm") + icon_result=":web_storm:" + ;; + "微信" | "WeChat") + icon_result=":wechat:" + ;; + "企业微信" | "WeCom") + icon_result=":wecom:" + ;; + "WezTerm") + icon_result=":wezterm:" + ;; + "WhatsApp" | "WhatsApp") + icon_result=":whats_app:" + ;; + "Xcode") + icon_result=":xcode:" + ;; + "Яндекс Музыка") + icon_result=":yandex_music:" + ;; + "Yuque" | "语雀") + icon_result=":yuque:" + ;; + "Zed") + icon_result=":zed:" + ;; + "Zeplin") + icon_result=":zeplin:" + ;; + "zoom.us") + icon_result=":zoom:" + ;; + "Zotero") + icon_result=":zotero:" + ;; + "Zulip") + icon_result=":zulip:" + ;; + *) + icon_result=":default:" + ;; + esac +} +### END-OF-ICON-MAP +__icon_map "$1" +echo "$icon_result" diff --git a/mac/.config/sketchybar/plugins/monitor_watcher.sh b/mac/.config/sketchybar/plugins/monitor_watcher.sh new file mode 100755 index 0000000..50868d3 --- /dev/null +++ b/mac/.config/sketchybar/plugins/monitor_watcher.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Store current monitor state to detect changes +MONITOR_STATE_FILE="/tmp/aerospace_monitor_state" + +# Get current monitor state +CURRENT_MONITORS=$(aerospace list-monitors | awk '{print $1}' | sort | tr '\n' ' ') + +# Check if state has changed +if [ -f "$MONITOR_STATE_FILE" ]; then + PREVIOUS_MONITORS=$(cat "$MONITOR_STATE_FILE") + if [ "$CURRENT_MONITORS" != "$PREVIOUS_MONITORS" ]; then + # Monitor configuration changed, update display + "$CONFIG_DIR/plugins/aerospace_display.sh" + fi +else + # First run, create state file + "$CONFIG_DIR/plugins/aerospace_display.sh" +fi + +# Save current state +echo "$CURRENT_MONITORS" > "$MONITOR_STATE_FILE"
\ No newline at end of file diff --git a/mac/.config/sketchybar/plugins/now_playing.sh b/mac/.config/sketchybar/plugins/now_playing.sh new file mode 100755 index 0000000..0ae68c7 --- /dev/null +++ b/mac/.config/sketchybar/plugins/now_playing.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Function to get Spotify info +get_spotify_info() { + local state=$(osascript -e 'tell application "Spotify" to player state as string' 2>/dev/null) + if [[ "$state" == "playing" ]]; then + local artist=$(osascript -e 'tell application "Spotify" to artist of current track as string' 2>/dev/null) + local track=$(osascript -e 'tell application "Spotify" to name of current track as string' 2>/dev/null) + echo "playing|$artist|$track" + elif [[ "$state" == "paused" ]]; then + echo "paused" + else + echo "stopped" + fi +} + +# Function to get Apple Music info +get_apple_music_info() { + local state=$(osascript -e 'tell application "Music" to player state as string' 2>/dev/null) + if [[ "$state" == "playing" ]]; then + local artist=$(osascript -e 'tell application "Music" to artist of current track as string' 2>/dev/null) + local track=$(osascript -e 'tell application "Music" to name of current track as string' 2>/dev/null) + echo "playing|$artist|$track" + elif [[ "$state" == "paused" ]]; then + echo "paused" + else + echo "stopped" + fi +} + +# Check Spotify first, then Apple Music +SPOTIFY_INFO=$(get_spotify_info) +APPLE_MUSIC_INFO=$(get_apple_music_info) + +if [[ "$SPOTIFY_INFO" == "playing|"* ]]; then + # Spotify is playing - show the item + sketchybar --set "$NAME" drawing=on + ICON="" + COLOR=$ACCENT_SECONDARY + IFS='|' read -r state artist track <<< "$SPOTIFY_INFO" + if [[ ${#track} -gt 20 ]]; then + LABEL="${track:0:20}..." + else + LABEL="$track" + fi +elif [[ "$APPLE_MUSIC_INFO" == "playing|"* ]]; then + # Apple Music is playing - show the item + sketchybar --set "$NAME" drawing=on + ICON="" + COLOR=$ACCENT_QUATERNARY + IFS='|' read -r state artist track <<< "$APPLE_MUSIC_INFO" + if [[ ${#track} -gt 20 ]]; then + LABEL="${track:0:20}..." + else + LABEL="$track" + fi +elif [[ "$SPOTIFY_INFO" == "paused" ]] || [[ "$APPLE_MUSIC_INFO" == "paused" ]]; then + # Music is paused - show paused state + sketchybar --set "$NAME" drawing=on + ICON="" + COLOR=$ACCENT_TERTIARY + LABEL="Paused" +else + # No music playing - hide the item completely + sketchybar --set "$NAME" drawing=off + exit 0 +fi + +# Update the Now Playing item (only if we're showing it) +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label="$LABEL" \ + label.color=$WHITE \ + label.font="SF Pro:Medium:12.0"
\ No newline at end of file diff --git a/mac/.config/sketchybar/plugins/space.sh b/mac/.config/sketchybar/plugins/space.sh new file mode 100755 index 0000000..b8602b5 --- /dev/null +++ b/mac/.config/sketchybar/plugins/space.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# The $SELECTED variable is available for space components and indicates if +# the space invoking this script (with name: $NAME) is currently selected: +# https://felixkratz.github.io/SketchyBar/config/components#space----associate-mission-control-spaces-with-an-item + +sketchybar --set "$NAME" background.drawing="$SELECTED" diff --git a/mac/.config/sketchybar/plugins/space_windows.sh b/mac/.config/sketchybar/plugins/space_windows.sh new file mode 100755 index 0000000..c8996cb --- /dev/null +++ b/mac/.config/sketchybar/plugins/space_windows.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +echo AEROSPACE_PREV_WORKSPACE: $AEROSPACE_PREV_WORKSPACE, \ + AEROSPACE_FOCUSED_WORKSPACE: $AEROSPACE_FOCUSED_WORKSPACE \ + SELECTED: $SELECTED \ + BG2: $BG2 \ + INFO: $INFO \ + SENDER: $SENDER \ + NAME: $NAME \ + >> ~/aaaa + +source "$CONFIG_DIR/colors.sh" + +AEROSPACE_FOCUSED_MONITOR=$(aerospace list-monitors --focused | awk '{print $1}') +AEROSAPCE_WORKSPACE_FOCUSED_MONITOR=$(aerospace list-workspaces --monitor focused --empty no) +AEROSPACE_EMPTY_WORKESPACE=$(aerospace list-workspaces --monitor focused --empty) + +reload_workspace_icon() { + # echo reload_workspace_icon "$@" >> ~/aaaa + apps=$(aerospace list-windows --workspace "$@" | awk -F'|' '{gsub(/^ *| *$/, "", $2); print $2}') + + icon_strip=" " + if [ "${apps}" != "" ]; then + while read -r app + do + icon_strip+=" $($CONFIG_DIR/plugins/icon_map.sh "$app")" + done <<< "${apps}" + else + icon_strip=" —" + fi + + sketchybar --animate sin 10 --set space.$@ label="$icon_strip" +} + +if [ "$SENDER" = "aerospace_workspace_change" ]; then + + # if [ $i = "$FOCUSED_WORKSPACE" ]; then + # sketchybar --set space.$FOCUSED_WORKSPACE background.drawing=on + # else + # sketchybar --set space.$FOCUSED_WORKSPACE background.drawing=off + # fi + #echo 'space_windows_change: '$AEROSPACE_FOCUSED_WORKSPACE >> ~/aaaa + #echo space: $space >> ~/aaaa + #space="$(echo "$INFO" | jq -r '.space')" + #apps="$(echo "$INFO" | jq -r '.apps | keys[]')" + # apps=$(aerospace list-windows --workspace $AEROSPACE_FOCUSED_WORKSPACE | awk -F'|' '{gsub(/^ *| *$/, "", $2); print $2}') + # + # icon_strip=" " + # if [ "${apps}" != "" ]; then + # while read -r app + # do + # icon_strip+=" $($CONFIG_DIR/plugins/icon_map.sh "$app")" + # done <<< "${apps}" + # else + # icon_strip=" —" + # fi + + reload_workspace_icon "$AEROSPACE_PREV_WORKSPACE" + reload_workspace_icon "$AEROSPACE_FOCUSED_WORKSPACE" + + #sketchybar --animate sin 10 --set space.$space label="$icon_strip" + + # current workspace space border color + sketchybar --set space.$AEROSPACE_FOCUSED_WORKSPACE icon.highlight=true \ + label.highlight=true \ + background.border_color=$GREY + + # prev workspace space border color + sketchybar --set space.$AEROSPACE_PREV_WORKSPACE icon.highlight=false \ + label.highlight=false \ + background.border_color=$BACKGROUND_2 + + # if [ "$AEROSPACE_FOCUSED_WORKSPACE" -gt 3 ]; then + # sketchybar --animate sin 10 --set space.$AEROSPACE_FOCUSED_WORKSPACE display=1 + # fi + ## focused 된 모니터에 space 상태 보이게 설정 + for i in $AEROSAPCE_WORKSPACE_FOCUSED_MONITOR; do + sketchybar --set space.$i display=$AEROSPACE_FOCUSED_MONITOR + done + + for i in $AEROSPACE_EMPTY_WORKESPACE; do + sketchybar --set space.$i display=0 + done + + sketchybar --set space.$AEROSPACE_FOCUSED_WORKSPACE display=$AEROSPACE_FOCUSED_MONITOR + +fi diff --git a/mac/.config/sketchybar/plugins/test_click.sh b/mac/.config/sketchybar/plugins/test_click.sh new file mode 100644 index 0000000..7cb66f2 --- /dev/null +++ b/mac/.config/sketchybar/plugins/test_click.sh @@ -0,0 +1,3 @@ +#/bin/bash -c + +osascript -e 'display notification "Volume clicked' diff --git a/mac/.config/sketchybar/plugins/volume.sh b/mac/.config/sketchybar/plugins/volume.sh new file mode 100755 index 0000000..6135b1f --- /dev/null +++ b/mac/.config/sketchybar/plugins/volume.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Get volume information +if [ "$SENDER" = "volume_change" ]; then + VOLUME="$INFO" + # Check if muted by trying to get current mute state + MUTED=$(osascript -e "output muted of (get volume settings)" 2>/dev/null) +else + VOLUME=$(osascript -e "output volume of (get volume settings)" 2>/dev/null) + MUTED=$(osascript -e "output muted of (get volume settings)" 2>/dev/null) +fi + +# Fallback if osascript fails +if [[ -z "$VOLUME" ]]; then + VOLUME=50 +fi + +# Determine icon and color based on volume level and mute status +if [[ $MUTED == "true" ]]; then + ICON="" # Muted icon + COLOR=$RED + LABEL="" # No label for muted state since we're not showing labels +else + if [[ $VOLUME -gt 75 ]]; then + ICON="" # High volume + COLOR=$ACCENT_PRIMARY + elif [[ $VOLUME -gt 50 ]]; then + ICON="" # Medium volume + COLOR=$ACCENT_PRIMARY + elif [[ $VOLUME -gt 25 ]]; then + ICON="" # Low volume + COLOR=$YELLOW + elif [[ $VOLUME -gt 0 ]]; then + ICON="" # Very low volume + COLOR=$ORANGE + else + ICON="" # No volume + COLOR=$RED + fi + LABEL="" # No label since we're not showing labels in the bar +fi + +# Update the volume item +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label="$LABEL" + +# Update popup if it's currently showing +if [ "$(sketchybar --query volume | jq -r '.popup.drawing')" = "on" ]; then + # Update the slider bar + SLIDER_BAR="" + FILLED_SEGMENTS=$((VOLUME / 2)) + + for i in {1..50}; do + if [ $i -le $FILLED_SEGMENTS ]; then + SLIDER_BAR="${SLIDER_BAR}█" + else + SLIDER_BAR="${SLIDER_BAR}▒" + fi + done + + # Update mute button + if [[ $MUTED == "true" ]]; then + MUTE_ICON="" + MUTE_COLOR=$RED + else + MUTE_ICON="" + MUTE_COLOR=$GREEN + fi + + sketchybar --set volume.mute icon="$MUTE_ICON" icon.color="$MUTE_COLOR" + sketchybar --set volume.slider icon="$SLIDER_BAR" + sketchybar --set volume.percent icon="$VOLUME%" +fi diff --git a/mac/.config/sketchybar/plugins/volume_click.sh b/mac/.config/sketchybar/plugins/volume_click.sh new file mode 100755 index 0000000..82badb8 --- /dev/null +++ b/mac/.config/sketchybar/plugins/volume_click.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Toggle popup +sketchybar --set volume popup.drawing=toggle + +# Get current volume and mute status +VOLUME=$(osascript -e "output volume of (get volume settings)" 2>/dev/null || echo "50") +MUTED=$(osascript -e "output muted of (get volume settings)" 2>/dev/null || echo "false") + +# Add mute toggle +if [ "$MUTED" = "true" ]; then + MUTE_ICON="" + MUTE_COLOR=$RED +else + MUTE_ICON="" + MUTE_COLOR=$GREEN +fi + +sketchybar --add item volume.mute popup.volume \ + --set volume.mute icon="$MUTE_ICON" \ + icon.color="$MUTE_COLOR" \ + label.drawing=off \ + background.drawing=off \ + padding_left=8 \ + padding_right=2 \ + click_script="osascript -e 'set volume output muted not (output muted of (get volume settings))'" + +# Add volume down button +sketchybar --add item volume.down popup.volume \ + --set volume.down icon="−" \ + icon.color=$WHITE \ + icon.font="SF Pro:Medium:14.0" \ + label.drawing=off \ + background.drawing=off \ + padding_left=2 \ + padding_right=2 \ + click_script="osascript -e 'set volume output volume ((output volume of (get volume settings)) - 5)'" + +# Create compact slider bar with 50 segments +SLIDER_BAR="" +FILLED_SEGMENTS=$((VOLUME / 2)) + +for i in {1..50}; do + if [ $i -le $FILLED_SEGMENTS ]; then + SLIDER_BAR="${SLIDER_BAR}█" + else + SLIDER_BAR="${SLIDER_BAR}▒" + fi +done + +sketchybar --add item volume.slider popup.volume \ + --set volume.slider icon="$SLIDER_BAR" \ + icon.color=$ACCENT_PRIMARY \ + icon.font="SF Pro:Regular:2.0" \ + label.drawing=off \ + background.drawing=off \ + padding_left=2 \ + padding_right=2 \ + click_script="osascript -e 'set volume output volume 50'" + +# Add volume up button +sketchybar --add item volume.up popup.volume \ + --set volume.up icon="+" \ + icon.color=$WHITE \ + icon.font="SF Pro:Medium:14.0" \ + label.drawing=off \ + background.drawing=off \ + padding_left=2 \ + padding_right=2 \ + click_script="osascript -e 'set volume output volume ((output volume of (get volume settings)) + 5)'" + +# Add volume percentage +sketchybar --add item volume.percent popup.volume \ + --set volume.percent icon="$VOLUME%" \ + icon.color=$WHITE \ + icon.font="SF Pro:Medium:9.0" \ + label.drawing=off \ + background.drawing=off \ + padding_left=2 diff --git a/mac/.config/sketchybar/plugins/weather.sh b/mac/.config/sketchybar/plugins/weather.sh new file mode 100755 index 0000000..b96bab8 --- /dev/null +++ b/mac/.config/sketchybar/plugins/weather.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Cache file for weather data +CACHE_FILE="/tmp/sketchybar_weather_cache" +CACHE_DURATION=1800 # 30 minutes + +# Function to get weather data +get_weather() { + # You can replace this with your preferred weather API + # For now, using a simple placeholder + local location="San Francisco" # Change to your location + + # Try to get weather from wttr.in (simple text-based weather) + local weather_data=$(curl -s "wttr.in/$location?format=3" 2>/dev/null) + + if [ -n "$weather_data" ]; then + echo "$weather_data" + else + echo "Weather unavailable" + fi +} + +# Check if cache is valid +if [ -f "$CACHE_FILE" ]; then + cache_time=$(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0) + current_time=$(date +%s) + + if [ $((current_time - cache_time)) -lt $CACHE_DURATION ]; then + weather=$(cat "$CACHE_FILE") + else + weather=$(get_weather) + echo "$weather" > "$CACHE_FILE" + fi +else + weather=$(get_weather) + echo "$weather" > "$CACHE_FILE" +fi + +# Extract temperature and condition +if [[ "$weather" =~ ([0-9.-]+°[CF]) ]]; then + temp="${BASH_REMATCH[1]}" + sketchybar --set "$NAME" label="$temp" \ + icon.color=$BLUE \ + label.color=$WHITE +else + sketchybar --set "$NAME" label="N/A" \ + icon.color=$GREY \ + label.color=$GREY +fi diff --git a/mac/.config/sketchybar/plugins/wifi.sh b/mac/.config/sketchybar/plugins/wifi.sh new file mode 100755 index 0000000..408fd00 --- /dev/null +++ b/mac/.config/sketchybar/plugins/wifi.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +# Source colors for consistent theming +source "$CONFIG_DIR/colors.sh" + +# Multiple methods to detect WiFi status +WIFI_CONNECTED=false +WIFI_SSID="" + +# Method 1: Check if WiFi interface is up and has IP +WIFI_IP=$(ifconfig en0 2>/dev/null | grep "inet " | awk '{print $2}' | head -1) +if [[ -n "$WIFI_IP" && "$WIFI_IP" != "127.0.0.1" ]]; then + # Method 2: Get network name using networksetup + WIFI_INFO=$(networksetup -getairportnetwork en0 2>/dev/null) + if [[ "$WIFI_INFO" != *"You are not associated"* ]] && [[ "$WIFI_INFO" != *"not found"* ]]; then + WIFI_SSID=$(echo "$WIFI_INFO" | sed 's/Current Wi-Fi Network: //') + WIFI_CONNECTED=true + fi +fi + +# Method 3: Alternative check using system_profiler (slower but more reliable) +if [[ "$WIFI_CONNECTED" == false ]]; then + WIFI_STATUS=$(system_profiler SPAirPortDataType 2>/dev/null | grep -A 1 "Current Network Information:" | grep "^[[:space:]]*[^:]" | head -1 | xargs) + if [[ -n "$WIFI_STATUS" && "$WIFI_STATUS" != "" ]]; then + WIFI_SSID="$WIFI_STATUS" + WIFI_CONNECTED=true + fi +fi + +# Method 4: Check using scutil (most reliable) +if [[ "$WIFI_CONNECTED" == false ]]; then + WIFI_CHECK=$(scutil --nc list | grep Connected | head -1) + if [[ -n "$WIFI_CHECK" ]]; then + WIFI_CONNECTED=true + WIFI_SSID="Connected" + fi +fi + +# Set icon and color based on connection status +if [[ "$WIFI_CONNECTED" == true ]]; then + # WiFi is connected - green icon + ICON="" + COLOR=$ACCENT_SECONDARY # Green +else + # WiFi is disconnected - gray icon + ICON="" + COLOR=$GREY +fi + +# Update the WiFi item - icon only, no label +sketchybar --set "$NAME" icon="$ICON" \ + icon.color="$COLOR" \ + label.drawing=off diff --git a/mac/.config/sketchybar/plugins/zen.sh b/mac/.config/sketchybar/plugins/zen.sh new file mode 100755 index 0000000..38f2291 --- /dev/null +++ b/mac/.config/sketchybar/plugins/zen.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +zen_on() { + sketchybar --set wifi drawing=off \ + --set apple.logo drawing=off \ + --set '/cpu.*/' drawing=off \ + --set calendar icon.drawing=off \ + --set separator drawing=off \ + --set front_app drawing=off \ + --set volume_icon drawing=off \ + --set spotify.anchor drawing=off \ + --set spotify.play updates=off \ + --set brew drawing=off \ + --set volume drawing=off \ + --set github.bell drawing=off +} + +zen_off() { + sketchybar --set wifi 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 volume_icon drawing=on \ + --set spotify.play updates=on \ + --set brew drawing=on \ + --set volume drawing=on \ + --set github.bell drawing=on +} + +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/mac/.config/sketchybar/reference.md b/mac/.config/sketchybar/reference.md new file mode 100644 index 0000000..9ba5418 --- /dev/null +++ b/mac/.config/sketchybar/reference.md @@ -0,0 +1,3 @@ +# Reference link +https://github.com/hbthen3rd/dotfiles/tree/master/.config/sketchybar + diff --git a/mac/.config/sketchybar/restart.sh b/mac/.config/sketchybar/restart.sh new file mode 100755 index 0000000..3cfcbaa --- /dev/null +++ b/mac/.config/sketchybar/restart.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Kill existing sketchybar instances +killall sketchybar + +# Wait a moment for processes to terminate +sleep 1 + +# Start sketchybar with new configuration +sketchybar --config "$HOME/.config/sketchybar/sketchybarrc" + +echo "SketchyBar restarted with new aesthetic configuration!" +echo "✨ Features included:" +echo " • Modern Catppuccin color scheme" +echo " • Beautiful aerospace workspace tiles" +echo " • Active workspace highlighting" +echo " • Enhanced battery, volume, and weather widgets" +echo " • Smooth animations and transitions" +echo " • Clean, minimal design"
\ No newline at end of file diff --git a/mac/.config/sketchybar/sketchybarrc b/mac/.config/sketchybar/sketchybarrc new file mode 100755 index 0000000..1169de5 --- /dev/null +++ b/mac/.config/sketchybar/sketchybarrc @@ -0,0 +1,287 @@ +#!/bin/bash + +# Modern aesthetic sketchybar configuration with aerospace integration +# Colors and icons are defined in separate files for better organization + +source "$CONFIG_DIR/colors.sh" +source "$CONFIG_DIR/icons.sh" + +PLUGIN_DIR="$CONFIG_DIR/plugins" + +##### Bar Appearance ##### +sketchybar --bar position=top height=42 \ + color=$BAR_COLOR \ + border_width=0 \ + corner_radius=0 \ + margin=0 \ + blur_radius=0 \ + padding_left=16 \ + padding_right=16 \ + shadow=off \ + sticky=on \ + topmost=window + +##### Changing Defaults ##### +default=( + updates=when_shown + icon.font="SF Pro:Semibold:15.0" + icon.color=$ICON_COLOR + icon.padding_left=6 + icon.padding_right=6 + label.font="SF Pro:Semibold:13.0" + label.color=$LABEL_COLOR + label.padding_left=6 + label.padding_right=6 + padding_left=8 + padding_right=8 + background.height=26 + background.corner_radius=6 + background.border_width=1 + background.border_color=$BACKGROUND_2 + popup.background.border_width=2 + popup.background.corner_radius=6 + popup.background.border_color=$POPUP_BORDER_COLOR + popup.background.color=$POPUP_BACKGROUND_COLOR +) + +sketchybar --default "${default[@]}" + +##### Left Side Items ##### + +# Apple Logo +sketchybar --add item apple.logo left \ + --set apple.logo icon=$APPLE \ + icon.font="SF Pro:Black:16.0" \ + icon.color=$ACCENT_SECONDARY \ + padding_right=12 \ + padding_left=4 \ + label.drawing=off \ + click_script="$PLUGIN_DIR/apple.sh" + +# Aerospace Display-Aware Workspaces +sketchybar --add event aerospace_workspace_change + +# Monitor 1 Workspace Indicator (Primary - Built-in Display) +sketchybar --add item monitor_1_workspace left \ + --subscribe monitor_1_workspace aerospace_workspace_change \ + --set monitor_1_workspace \ + icon="M1:4" \ + icon.font="SF Pro:Medium:12.0" \ + icon.color=$GREY \ + icon.padding_left=8 \ + icon.padding_right=8 \ + label.drawing=off \ + padding_left=4 \ + padding_right=4 \ + background.color=$BACKGROUND_1 \ + background.corner_radius=6 \ + background.height=26 \ + background.drawing=on \ + script="$PLUGIN_DIR/aerospace_display.sh" + +# Monitor 2 Workspace Indicator (External - MAG 274UPF E2) +sketchybar --add item monitor_2_workspace left \ + --subscribe monitor_2_workspace aerospace_workspace_change \ + --set monitor_2_workspace \ + icon="M2:1" \ + icon.font="SF Pro:Medium:12.0" \ + icon.color=$GREY \ + icon.padding_left=8 \ + icon.padding_right=8 \ + label.drawing=off \ + padding_left=4 \ + padding_right=4 \ + background.color=$BACKGROUND_1 \ + background.corner_radius=6 \ + background.height=26 \ + background.drawing=on \ + script="$PLUGIN_DIR/aerospace_display.sh" + +# Monitor Connection Watcher (detects when monitors are connected/disconnected) +sketchybar --add item monitor_watcher left \ + --set monitor_watcher \ + drawing=off \ + update_freq=5 \ + script="$PLUGIN_DIR/monitor_watcher.sh" + +# Separator +sketchybar --add item separator left \ + --set separator icon="" \ + icon.font="SF Pro:Regular:16.0" \ + icon.color=$ACCENT_TERTIARY \ + padding_left=12 \ + padding_right=8 \ + label.drawing=off + +# Front App +sketchybar --add item front_app left \ + --set front_app icon.drawing=on \ + icon.font="SF Pro:Semibold:15.0" \ + icon.color=$ACCENT_QUATERNARY \ + icon.padding_left=6 \ + icon.padding_right=8 \ + label.font="SF Pro:Medium:13.0" \ + label.color=$WHITE \ + label.padding_left=4 \ + label.padding_right=8 \ + padding_left=8 \ + padding_right=8 \ + script="$PLUGIN_DIR/front_app.sh" \ + --subscribe front_app front_app_switched + +##### Right Side Items ##### + + + +# Calendar Events +sketchybar --add item calendar right \ + --set calendar icon.font="SF Pro:Semibold:12.0" \ + icon.padding_left=8 \ + icon.padding_right=6 \ + label.font="SF Pro:Medium:10.0" \ + label.padding_left=4 \ + label.padding_right=8 \ + label.max_chars=25 \ + update_freq=300 \ + script="$PLUGIN_DIR/calendar.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + background.height=26 \ + padding_left=4 \ + padding_right=4 + +# Now Playing +sketchybar --add item now_playing right \ + --set now_playing icon.font="SF Pro:Semibold:15.0" \ + icon.padding_left=8 \ + icon.padding_right=6 \ + label.font="SF Pro:Medium:12.0" \ + label.padding_left=4 \ + label.padding_right=8 \ + update_freq=2 \ + script="$PLUGIN_DIR/now_playing.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + drawing=off \ + padding_left=4 \ + padding_right=4 + + + +# WiFi Status +sketchybar --add item wifi right \ + --set wifi icon.font="SF Pro:Semibold:15.0" \ + icon.padding_left=8 \ + icon.padding_right=8 \ + label.drawing=off \ + update_freq=10 \ + script="$PLUGIN_DIR/wifi.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 + +# Bluetooth Status +sketchybar --add item bluetooth right \ + --set bluetooth icon.font="SF Pro:Semibold:15.0" \ + icon.padding_left=9 \ + icon.padding_right=9 \ + label.drawing=off \ + update_freq=10 \ + script="$PLUGIN_DIR/bluetooth.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 + +# Clock +sketchybar --add item clock right \ + --set clock icon="" \ + icon.font="SF Pro:Semibold:15.0" \ + icon.color=$YELLOW \ + icon.padding_left=8 \ + icon.padding_right=6 \ + label.font="SF Pro:Medium:12.0" \ + label.color=$WHITE \ + label.padding_left=4 \ + label.padding_right=8 \ + update_freq=10 \ + script="$PLUGIN_DIR/clock.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 \ + click_script="$PLUGIN_DIR/clock_click.sh" + +# Volume +sketchybar --add item volume right \ + --set volume icon.font="SF Pro:Semibold:15.0" \ + icon.color=$ACCENT_PRIMARY \ + icon.padding_left=10 \ + icon.padding_right=12 \ + label.drawing=off \ + script="$PLUGIN_DIR/volume.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 \ + click_script="$PLUGIN_DIR/volume_click.sh" \ + popup.background.border_width=2 \ + popup.background.corner_radius=6 \ + popup.background.border_color=$POPUP_BORDER_COLOR \ + popup.background.color=$POPUP_BACKGROUND_COLOR \ + popup.horizontal=on \ + --subscribe volume volume_change + +# Battery +sketchybar --add item battery right \ + --set battery icon.font="SF Pro:Semibold:15.0" \ + icon.color=$ACCENT_SECONDARY \ + icon.padding_left=8 \ + icon.padding_right=6 \ + label.font="SF Pro:Medium:12.0" \ + label.color=$WHITE \ + label.padding_left=4 \ + label.padding_right=8 \ + update_freq=120 \ + script="$PLUGIN_DIR/battery.sh" \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 \ + --subscribe battery system_woke power_source_change + +# Pritunl VPN +sketchybar --add item pritunl right \ + --set pritunl icon="" \ + icon.font="SF Pro:Semibold:13.0" \ + icon.color=$ACCENT_PRIMARY \ + icon.padding_left=8 \ + icon.padding_right=10 \ + label.drawing=off \ + background.color=$BACKGROUND_1 \ + background.drawing=on \ + padding_left=4 \ + padding_right=4 \ + click_script="open -a Pritunl" + + +# Weather +# sketchybar --add item weather right \ +# --set weather icon="" \ +# icon.font="SF Pro:Semibold:15.0" \ +# icon.color=$BLUE \ +# icon.padding_left=8 \ +# icon.padding_right=6 \ +# label.padding_left=4 \ +# label.padding_right=8 \ +# update_freq=1800 \ +# script="$PLUGIN_DIR/weather.sh" \ +# background.color=$BACKGROUND_1 \ +# background.drawing=on \ +# padding_left=4 \ +# padding_right=4 + +##### Finalize Setup ##### +sketchybar --update + |
