summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne-Cole <77279425+Wacky404@users.noreply.github.com>2024-07-30 00:37:33 -0500
committerWayne-Cole <77279425+Wacky404@users.noreply.github.com>2024-07-30 00:37:33 -0500
commit1769ac995d65d33893eadab3185d9a5b0e7d2af8 (patch)
tree6f294db6421bc59f0771815433fd8df1dc54884a
parent87ea211cb78f95b63ed4a0cef38110cd544631e5 (diff)
downloadwackys-dev-env-1769ac995d65d33893eadab3185d9a5b0e7d2af8.tar.xz
wackys-dev-env-1769ac995d65d33893eadab3185d9a5b0e7d2af8.zip
chore: file update
-rw-r--r--.config/nvim/init.lua1
-rw-r--r--.config/nvim/lua/cole/plugins-setup.lua20
-rw-r--r--.config/nvim/lua/cole/plugins/dadbod-setup.lua7
-rw-r--r--.config/nvim/plugin/packer_compiled.lua14
-rw-r--r--.config/sketchybar/bar.lua11
-rw-r--r--.config/sketchybar/colors.lua35
-rw-r--r--.config/sketchybar/default.lua58
-rw-r--r--.config/sketchybar/helpers/.gitignore1
-rw-r--r--.config/sketchybar/helpers/app_icons.lua210
-rw-r--r--.config/sketchybar/helpers/default_font.lua13
-rw-r--r--.config/sketchybar/helpers/event_providers/cpu_load/cpu.h58
-rw-r--r--.config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c41
-rw-r--r--.config/sketchybar/helpers/event_providers/cpu_load/makefile5
-rw-r--r--.config/sketchybar/helpers/event_providers/makefile3
-rw-r--r--.config/sketchybar/helpers/event_providers/network_load/makefile5
-rw-r--r--.config/sketchybar/helpers/event_providers/network_load/network.h90
-rw-r--r--.config/sketchybar/helpers/event_providers/network_load/network_load.c42
-rw-r--r--.config/sketchybar/helpers/event_providers/sketchybar.h124
-rw-r--r--.config/sketchybar/helpers/init.lua4
-rwxr-xr-x.config/sketchybar/helpers/install.sh17
-rw-r--r--.config/sketchybar/helpers/makefile3
-rw-r--r--.config/sketchybar/helpers/menus/makefile5
-rw-r--r--.config/sketchybar/helpers/menus/menus.c248
-rw-r--r--.config/sketchybar/icons.lua92
-rw-r--r--.config/sketchybar/init.lua16
-rw-r--r--.config/sketchybar/items/apple.lua38
-rw-r--r--.config/sketchybar/items/calendar.lua50
-rw-r--r--.config/sketchybar/items/front_app.lua22
-rw-r--r--.config/sketchybar/items/init.lua7
-rw-r--r--.config/sketchybar/items/media.lua122
-rw-r--r--.config/sketchybar/items/menus.lua78
-rw-r--r--.config/sketchybar/items/spaces.lua186
-rw-r--r--.config/sketchybar/items/widgets/battery.lua117
-rw-r--r--.config/sketchybar/items/widgets/cpu.lua71
-rw-r--r--.config/sketchybar/items/widgets/func_utils.lua26
-rw-r--r--.config/sketchybar/items/widgets/init.lua4
-rw-r--r--.config/sketchybar/items/widgets/volume.lua157
-rw-r--r--.config/sketchybar/items/widgets/wifi.lua238
-rw-r--r--.config/sketchybar/settings.lua50
-rwxr-xr-x.config/sketchybar/sketchybarrc5
40 files changed, 2292 insertions, 2 deletions
diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua
index 1e046e8..b12b9b7 100644
--- a/.config/nvim/init.lua
+++ b/.config/nvim/init.lua
@@ -17,3 +17,4 @@ require("cole.plugins.gitsigns")
require("cole.plugins.formatter")
require("cole.plugins.vimtex-setup")
require("cole.plugins.linter-setup")
+require("cole.plugins.dadbod-setup")
diff --git a/.config/nvim/lua/cole/plugins-setup.lua b/.config/nvim/lua/cole/plugins-setup.lua
index fd54dab..5284389 100644
--- a/.config/nvim/lua/cole/plugins-setup.lua
+++ b/.config/nvim/lua/cole/plugins-setup.lua
@@ -105,6 +105,26 @@ return packer.startup(function(use)
end,
})
+ -- dadbod for Databases
+ use({
+ "kristijanhusak/vim-dadbod-ui",
+ requires = { 'tpope/vim-dadbod' },
+ dependencies = {
+ { 'kristijanhusak/vim-dadbod-completion',
+ ft = { 'sql' },
+ cmd = {
+ 'DBUI',
+ 'DBUIToggle',
+ 'DBUIAddConnection',
+ 'DBUIFindBuffer',
+ },
+ config = function()
+ -- place my small config changes here
+ vim.g.db_ui_use_nerd_fonts = 1
+ end,
+ } },
+ })
+
-- auto closing
use("windwp/nvim-autopairs") -- autoclose parens, brackets, quotes, etc...
use({ "windwp/nvim-ts-autotag", after = "nvim-treesitter" }) -- autoclose tags
diff --git a/.config/nvim/lua/cole/plugins/dadbod-setup.lua b/.config/nvim/lua/cole/plugins/dadbod-setup.lua
new file mode 100644
index 0000000..7af9cd5
--- /dev/null
+++ b/.config/nvim/lua/cole/plugins/dadbod-setup.lua
@@ -0,0 +1,7 @@
+local status, db_ui = pcall(require, "dadbod-ui")
+if not status then
+ return
+end
+
+vim.g.db_ui_variable_prefix = 'DB_'
+
diff --git a/.config/nvim/plugin/packer_compiled.lua b/.config/nvim/plugin/packer_compiled.lua
index e2c5b83..6410ebb 100644
--- a/.config/nvim/plugin/packer_compiled.lua
+++ b/.config/nvim/plugin/packer_compiled.lua
@@ -224,7 +224,7 @@ _G.packer_plugins = {
url = "https://github.com/nvim-telescope/telescope.nvim"
},
["toggleterm.nvim"] = {
- config = { "\27LJ\2\nf\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0005\2\3\0B\0\2\1K\0\1\0\1\0\3\14direction\15horizontal\tsize\3\15\14autochdir\1\nsetup\15toggleterm\frequire\0" },
+ config = { "\27LJ\2\nf\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0005\2\3\0B\0\2\1K\0\1\0\1\0\3\tsize\3\15\14autochdir\1\14direction\15horizontal\nsetup\15toggleterm\frequire\0" },
loaded = true,
path = "/Users/cole/.local/share/nvim/site/pack/packer/start/toggleterm.nvim",
url = "https://github.com/akinsho/toggleterm.nvim"
@@ -239,6 +239,16 @@ _G.packer_plugins = {
path = "/Users/cole/.local/share/nvim/site/pack/packer/start/vim-ReplaceWithRegister",
url = "https://github.com/inkarkat/vim-ReplaceWithRegister"
},
+ ["vim-dadbod"] = {
+ loaded = true,
+ path = "/Users/cole/.local/share/nvim/site/pack/packer/start/vim-dadbod",
+ url = "https://github.com/tpope/vim-dadbod"
+ },
+ ["vim-dadbod-ui"] = {
+ loaded = true,
+ path = "/Users/cole/.local/share/nvim/site/pack/packer/start/vim-dadbod-ui",
+ url = "https://github.com/kristijanhusak/vim-dadbod-ui"
+ },
["vim-maximizer"] = {
loaded = true,
path = "/Users/cole/.local/share/nvim/site/pack/packer/start/vim-maximizer",
@@ -268,7 +278,7 @@ try_loadstring("\27LJ\2\n=\0\0\2\0\4\0\0056\0\0\0009\0\1\0005\1\3\0=\1\2\0K\0\1\
time([[Setup for markdown-preview.nvim]], false)
-- Config for: toggleterm.nvim
time([[Config for toggleterm.nvim]], true)
-try_loadstring("\27LJ\2\nf\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0005\2\3\0B\0\2\1K\0\1\0\1\0\3\14direction\15horizontal\tsize\3\15\14autochdir\1\nsetup\15toggleterm\frequire\0", "config", "toggleterm.nvim")
+try_loadstring("\27LJ\2\nf\0\0\3\0\4\0\a6\0\0\0'\2\1\0B\0\2\0029\0\2\0005\2\3\0B\0\2\1K\0\1\0\1\0\3\tsize\3\15\14autochdir\1\14direction\15horizontal\nsetup\15toggleterm\frequire\0", "config", "toggleterm.nvim")
time([[Config for toggleterm.nvim]], false)
-- Load plugins in order defined by `after`
time([[Sequenced loading]], true)
diff --git a/.config/sketchybar/bar.lua b/.config/sketchybar/bar.lua
new file mode 100644
index 0000000..659ccae
--- /dev/null
+++ b/.config/sketchybar/bar.lua
@@ -0,0 +1,11 @@
+local colors = require("colors")
+
+-- Equivalent to the --bar domain
+sbar.bar({
+ topmost = "window",
+ height = 40,
+ -- changes the whole bar color
+ color = colors.transparent,
+ padding_right = 2,
+ padding_left = 2,
+})
diff --git a/.config/sketchybar/colors.lua b/.config/sketchybar/colors.lua
new file mode 100644
index 0000000..a664cfa
--- /dev/null
+++ b/.config/sketchybar/colors.lua
@@ -0,0 +1,35 @@
+return {
+ -- in hex
+ black = 0xff181819,
+ white = 0xffe2e2e3,
+ red = 0xfffc5d7c,
+ blood = 0xFF8A0303,
+ green = 0xff9ed072,
+ blue = 0xff76cce0,
+ cog_blue = 0xff6a97b8,
+ yellow = 0xffe7c664,
+ orange = 0xfff39660,
+ orange_brown = 0xffC46210,
+ magenta = 0xffb39df3,
+ grey = 0xff7f8490,
+ pink = 0xffffc0cb,
+ transparent = 0x00000000,
+
+ bar = {
+ bg = 0xf02c2e34,
+ border = 0xff2c2e34,
+ },
+ popup = {
+ bg = 0xc02c2e34,
+ border = 0xff7f8490,
+ },
+ bg1 = 0xff363944,
+ bg2 = 0xff414550,
+
+ with_alpha = function(color, alpha)
+ if alpha > 1.0 or alpha < 0.0 then
+ return color
+ end
+ return (color & 0x00ffffff) | (math.floor(alpha * 255.0) << 24)
+ end,
+}
diff --git a/.config/sketchybar/default.lua b/.config/sketchybar/default.lua
new file mode 100644
index 0000000..aec37a4
--- /dev/null
+++ b/.config/sketchybar/default.lua
@@ -0,0 +1,58 @@
+local settings = require("settings")
+local colors = require("colors")
+local sbar = require("sketchybar")
+
+-- Equivalent to the --default domain
+sbar.default({
+ updates = "when_shown",
+ icon = {
+ font = {
+ family = settings.font.text,
+ style = settings.font.style_map["Bold"],
+ size = 14.0,
+ },
+ -- changed the applel logo & cpu
+ color = settings.apple_icon,
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ background = { image = { corner_radius = 9 } },
+ },
+ label = {
+ font = {
+ family = settings.font.text,
+ style = settings.font.style_map["Semibold"],
+ size = 13.0,
+ },
+ -- text color for widgets
+ color = colors.white,
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ },
+ background = {
+ height = 28,
+ corner_radius = 9,
+ border_width = 2,
+ -- changes border color for widgets
+ border_color = settings.widget_borders,
+ image = {
+ corner_radius = 9,
+ border_color = colors.grey,
+ border_width = 1,
+ },
+ },
+ popup = {
+ background = {
+ border_width = 2,
+ corner_radius = 9,
+ -- colors.popup.border
+ border_color = colors.popup.border,
+ -- colors.popup.bg
+ color = colors.popup.bg,
+ shadow = { drawing = true },
+ },
+ blur_radius = 50,
+ },
+ padding_left = 5,
+ padding_right = 5,
+ scroll_texts = true,
+})
diff --git a/.config/sketchybar/helpers/.gitignore b/.config/sketchybar/helpers/.gitignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/.config/sketchybar/helpers/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/.config/sketchybar/helpers/app_icons.lua b/.config/sketchybar/helpers/app_icons.lua
new file mode 100644
index 0000000..3487782
--- /dev/null
+++ b/.config/sketchybar/helpers/app_icons.lua
@@ -0,0 +1,210 @@
+return {
+ ["Typora"] = ":text:",
+ ["Orion"] = ":orion:",
+ ["Orion RC"] = ":orion:",
+ ["Grammarly Editor"] = ":grammarly:",
+ ["kitty"] = ":kitty:",
+ ["ClickUp"] = ":click_up:",
+ ["Iris"] = ":iris:",
+ ["PomoDone App"] = ":pomodone:",
+ ["qutebrowser"] = ":qute_browser:",
+ ["Raindrop.io"] = ":raindrop_io:",
+ ["Airmail"] = ":airmail:",
+ ["Affinity Publisher 2"] = ":affinity_publisher_2:",
+ ["Calendar"] = ":calendar:",
+ ["日历"] = ":calendar:",
+ ["Fantastical"] = ":calendar:",
+ ["Cron"] = ":calendar:",
+ ["Amie"] = ":calendar:",
+ ["Figma"] = ":figma:",
+ ["Element"] = ":element:",
+ ["Signal"] = ":signal:",
+ ["Mattermost"] = ":mattermost:",
+ ["Caprine"] = ":caprine:",
+ ["Microsoft To Do"] = ":things:",
+ ["Things"] = ":things:",
+ ["Godot"] = ":godot:",
+ ["Android Messages"] = ":android_messages:",
+ ["Zed"] = ":zed:",
+ ["Anytype"] = ":anytype:",
+ ["TeamSpeak 3"] = ":team_speak:",
+ ["LibreWolf"] = ":libre_wolf:",
+ ["neovide"] = ":neovide:",
+ ["Spotlight"] = ":spotlight:",
+ ["微信"] = ":wechat:",
+ ["Dropbox"] = ":dropbox:",
+ ["Transmit"] = ":transmit:",
+ ["TickTick"] = ":tick_tick:",
+ ["Parallels Desktop"] = ":parallels:",
+ ["Audacity"] = ":audacity:",
+ ["Rider"] = ":rider:",
+ ["JetBrains Rider"] = ":rider:",
+ ["DEVONthink 3"] = ":devonthink3:",
+ ["Docker"] = ":docker:",
+ ["Docker Desktop"] = ":docker:",
+ ["Matlab"] = ":matlab:",
+ ["VLC"] = ":vlc:",
+ ["Alacritty"] = ":alacritty:",
+ ["Pages"] = ":pages:",
+ ["Pages 文稿"] = ":pages:",
+ ["Bear"] = ":bear:",
+ ["Pine"] = ":pine:",
+ ["Affinity Designer 2"] = ":affinity_designer_2:",
+ ["Keyboard Maestro"] = ":keyboard_maestro:",
+ ["Joplin"] = ":joplin:",
+ ["mpv"] = ":mpv:",
+ ["zoom.us"] = ":zoom:",
+ ["Affinity Photo 2"] = ":affinity_photo_2:",
+ ["Music"] = ":music:",
+ ["音乐"] = ":music:",
+ ["League of Legends"] = ":league_of_legends:",
+ ["Tor Browser"] = ":tor_browser:",
+ ["Hyper"] = ":hyper:",
+ ["‎WhatsApp"] = ":whats_app:",
+ ["카카오톡"] = ":kakaotalk:",
+ ["Discord"] = ":discord:",
+ ["Discord Canary"] = ":discord:",
+ ["Discord PTB"] = ":discord:",
+ ["Neovide"] = ":vim:",
+ ["MacVim"] = ":vim:",
+ ["Vim"] = ":vim:",
+ ["VimR"] = ":vim:",
+ ["Keynote"] = ":keynote:",
+ ["Keynote 讲演"] = ":keynote:",
+ ["iTerm"] = ":iterm:",
+ ["IntelliJ IDEA"] = ":idea:",
+ ["Finder"] = ":finder:",
+ ["访达"] = ":finder:",
+ ["Xcode"] = ":xcode:",
+ ["GoLand"] = ":goland:",
+ ["Android Studio"] = ":android_studio:",
+ ["MoneyMoney"] = ":bank:",
+ ["Spotify"] = ":spotify:",
+ ["KeePassXC"] = ":kee_pass_x_c:",
+ ["Alfred"] = ":alfred:",
+ ["Color Picker"] = ":color_picker:",
+ ["数码测色计"] = ":color_picker:",
+ ["Microsoft Word"] = ":microsoft_word:",
+ ["Microsoft PowerPoint"] = ":microsoft_power_point:",
+ ["Notes"] = ":notes:",
+ ["备忘录"] = ":notes:",
+ ["Microsoft Edge"] = ":microsoft_edge:",
+ ["Sublime Text"] = ":sublime_text:",
+ ["Sequel Ace"] = ":sequel_ace:",
+ ["Folx"] = ":folx:",
+ ["DingTalk"] = ":dingtalk:",
+ ["钉钉"] = ":dingtalk:",
+ ["阿里钉"] = ":dingtalk:",
+ ["WebStorm"] = ":web_storm:",
+ ["Sequel Pro"] = ":sequel_pro:",
+ ["Skype"] = ":skype:",
+ ["网易云音乐"] = ":netease_music:",
+ ["PyCharm"] = ":pycharm:",
+ ["Canary Mail"] = ":mail:",
+ ["HEY"] = ":mail:",
+ ["Mail"] = ":mail:",
+ ["Mailspring"] = ":mail:",
+ ["MailMate"] = ":mail:",
+ ["邮件"] = ":mail:",
+ ["Default"] = ":default:",
+ ["App Store"] = ":app_store:",
+ ["Calibre"] = ":book:",
+ ["Todoist"] = ":todoist:",
+ ["Emacs"] = ":emacs:",
+ ["Messenger"] = ":messenger:",
+ ["Tower"] = ":tower:",
+ ["VSCodium"] = ":vscodium:",
+ ["Drafts"] = ":drafts:",
+ ["Cypress"] = ":cypress:",
+ ["GitHub Desktop"] = ":git_hub:",
+ ["Telegram"] = ":telegram:",
+ ["Firefox Developer Edition"] = ":firefox_developer_edition:",
+ ["Firefox Nightly"] = ":firefox_developer_edition:",
+ ["Min"] = ":min_browser:",
+ ["Sketch"] = ":sketch:",
+ ["Affinity Photo"] = ":affinity_photo:",
+ ["MAMP"] = ":mamp:",
+ ["MAMP PRO"] = ":mamp:",
+ ["Insomnia"] = ":insomnia:",
+ ["Bitwarden"] = ":bit_warden:",
+ ["Warp"] = ":warp:",
+ ["System Preferences"] = ":gear:",
+ ["System Settings"] = ":gear:",
+ ["系统设置"] = ":gear:",
+ ["Affinity Designer"] = ":affinity_designer:",
+ ["Live"] = ":ableton:",
+ ["Arc"] = ":arc:",
+ ["Chromium"] = ":google_chrome:",
+ ["Google Chrome"] = ":google_chrome:",
+ ["Google Chrome Canary"] = ":google_chrome:",
+ ["Jellyfin Media Player"] = ":jellyfin:",
+ ["Zulip"] = ":zulip:",
+ ["1Password"] = ":one_password:",
+ ["FaceTime"] = ":face_time:",
+ ["FaceTime 通话"] = ":face_time:",
+ ["Citrix Workspace"] = ":citrix:",
+ ["Citrix Viewer"] = ":citrix:",
+ ["Logseq"] = ":logseq:",
+ ["Reeder"] = ":reeder5:",
+ ["Code"] = ":code:",
+ ["Code - Insiders"] = ":code:",
+ ["Notion"] = ":notion:",
+ ["Final Cut Pro"] = ":final_cut_pro:",
+ ["Zotero"] = ":zotero:",
+ ["Safari"] = ":safari:",
+ ["Safari浏览器"] = ":safari:",
+ ["Safari Technology Preview"] = ":safari:",
+ ["Blender"] = ":blender:",
+ ["Affinity Publisher"] = ":affinity_publisher:",
+ ["Spark Desktop"] = ":spark:",
+ ["Zeplin"] = ":zeplin:",
+ ["Replit"] = ":replit:",
+ ["Podcasts"] = ":podcasts:",
+ ["播客"] = ":podcasts:",
+ ["NordVPN"] = ":nord_vpn:",
+ ["Notability"] = ":notability:",
+ ["Numbers"] = ":numbers:",
+ ["Numbers 表格"] = ":numbers:",
+ ["Nova"] = ":nova:",
+ ["Microsoft Excel"] = ":microsoft_excel:",
+ ["Trello"] = ":trello:",
+ ["Pi-hole Remote"] = ":pihole:",
+ ["Linear"] = ":linear:",
+ ["CleanMyMac X"] = ":desktop:",
+ ["GrandTotal"] = ":dollar:",
+ ["Receipts"] = ":dollar:",
+ ["Evernote Legacy"] = ":evernote_legacy:",
+ ["OmniFocus"] = ":omni_focus:",
+ ["Terminal"] = ":terminal:",
+ ["终端"] = ":terminal:",
+ ["Atom"] = ":atom:",
+ ["Kakoune"] = ":kakoune:",
+ ["Reminders"] = ":reminders:",
+ ["提醒事项"] = ":reminders:",
+ ["Tana"] = ":tana:",
+ ["OBS"] = ":obsstudio:",
+ ["VMware Fusion"] = ":vmware_fusion:",
+ ["Tweetbot"] = ":twitter:",
+ ["Twitter"] = ":twitter:",
+ ["Microsoft Teams"] = ":microsoft_teams:",
+ ["Yuque"] = ":yuque:",
+ ["语雀"] = ":yuque:",
+ ["Slack"] = ":slack:",
+ ["Vivaldi"] = ":vivaldi:",
+ ["Setapp"] = ":setapp:",
+ ["TIDAL"] = ":tidal:",
+ ["Miro"] = ":miro:",
+ ["Messages"] = ":messages:",
+ ["信息"] = ":messages:",
+ ["Nachrichten"] = ":messages:",
+ ["Brave Browser"] = ":brave_browser:",
+ ["Preview"] = ":pdf:",
+ ["预览"] = ":pdf:",
+ ["Skim"] = ":pdf:",
+ ["zathura"] = ":pdf:",
+ ["Obsidian"] = ":obsidian:",
+ ["Thunderbird"] = ":thunderbird:",
+ ["Firefox"] = ":firefox:",
+ ["WezTerm"] = ":wezterm:",
+ ["default"] = ":default:",
+}
diff --git a/.config/sketchybar/helpers/default_font.lua b/.config/sketchybar/helpers/default_font.lua
new file mode 100644
index 0000000..fb1f16e
--- /dev/null
+++ b/.config/sketchybar/helpers/default_font.lua
@@ -0,0 +1,13 @@
+return {
+ text = "SF Pro", -- Used for text
+ numbers = "SF Mono", -- Used for numbers
+
+ -- Unified font style map
+ style_map = {
+ ["Regular"] = "Regular",
+ ["Semibold"] = "Semibold",
+ ["Bold"] = "Bold",
+ ["Heavy"] = "Heavy",
+ ["Black"] = "Black",
+ }
+}
diff --git a/.config/sketchybar/helpers/event_providers/cpu_load/cpu.h b/.config/sketchybar/helpers/event_providers/cpu_load/cpu.h
new file mode 100644
index 0000000..413f70f
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/cpu_load/cpu.h
@@ -0,0 +1,58 @@
+#include <mach/mach.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdio.h>
+
+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;
+
+ int user_load;
+ int sys_load;
+ int total_load;
+};
+
+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;
+}
+
+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];
+
+ cpu->user_load = (double)delta_user / (double)(delta_system
+ + delta_user
+ + delta_idle) * 100.0;
+
+ cpu->sys_load = (double)delta_system / (double)(delta_system
+ + delta_user
+ + delta_idle) * 100.0;
+
+ cpu->total_load = cpu->user_load + cpu->sys_load;
+ }
+
+ cpu->prev_load = cpu->load;
+ cpu->has_prev_load = true;
+}
diff --git a/.config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c b/.config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c
new file mode 100644
index 0000000..ee97613
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/cpu_load/cpu_load.c
@@ -0,0 +1,41 @@
+#include "cpu.h"
+#include "../sketchybar.h"
+
+int main (int argc, char** argv) {
+ float update_freq;
+ if (argc < 3 || (sscanf(argv[2], "%f", &update_freq) != 1)) {
+ printf("Usage: %s \"<event-name>\" \"<event_freq>\"\n", argv[0]);
+ exit(1);
+ }
+
+ alarm(0);
+ struct cpu cpu;
+ cpu_init(&cpu);
+
+ // Setup the event in sketchybar
+ char event_message[512];
+ snprintf(event_message, 512, "--add event '%s'", argv[1]);
+ sketchybar(event_message);
+
+ char trigger_message[512];
+ for (;;) {
+ // Acquire new info
+ cpu_update(&cpu);
+
+ // Prepare the event message
+ snprintf(trigger_message,
+ 512,
+ "--trigger '%s' user_load='%d' sys_load='%02d' total_load='%02d'",
+ argv[1],
+ cpu.user_load,
+ cpu.sys_load,
+ cpu.total_load );
+
+ // Trigger the event
+ sketchybar(trigger_message);
+
+ // Wait
+ usleep(update_freq * 1000000);
+ }
+ return 0;
+}
diff --git a/.config/sketchybar/helpers/event_providers/cpu_load/makefile b/.config/sketchybar/helpers/event_providers/cpu_load/makefile
new file mode 100644
index 0000000..6366a0f
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/cpu_load/makefile
@@ -0,0 +1,5 @@
+bin/cpu_load: cpu_load.c cpu.h ../sketchybar.h | bin
+ clang -std=c99 -O3 $< -o $@
+
+bin:
+ mkdir bin
diff --git a/.config/sketchybar/helpers/event_providers/makefile b/.config/sketchybar/helpers/event_providers/makefile
new file mode 100644
index 0000000..8c1ca39
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/makefile
@@ -0,0 +1,3 @@
+all:
+ (cd cpu_load && $(MAKE))
+ (cd network_load && $(MAKE))
diff --git a/.config/sketchybar/helpers/event_providers/network_load/makefile b/.config/sketchybar/helpers/event_providers/network_load/makefile
new file mode 100644
index 0000000..e464482
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/network_load/makefile
@@ -0,0 +1,5 @@
+bin/network_load: network_load.c network.h ../sketchybar.h | bin
+ clang -std=c99 -O3 $< -o $@
+
+bin:
+ mkdir bin
diff --git a/.config/sketchybar/helpers/event_providers/network_load/network.h b/.config/sketchybar/helpers/event_providers/network_load/network.h
new file mode 100644
index 0000000..25175e5
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/network_load/network.h
@@ -0,0 +1,90 @@
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <net/if.h>
+#include <net/if_mib.h>
+#include <sys/select.h>
+#include <sys/sysctl.h>
+
+static char unit_str[3][6] = { { " Bps" }, { "KBps" }, { "MBps" }, };
+
+enum unit {
+ UNIT_BPS,
+ UNIT_KBPS,
+ UNIT_MBPS
+};
+struct network {
+ uint32_t row;
+ struct ifmibdata data;
+ struct timeval tv_nm1, tv_n, tv_delta;
+
+ int up;
+ int down;
+ enum unit up_unit, down_unit;
+};
+
+static inline void ifdata(uint32_t net_row, struct ifmibdata* data) {
+ static size_t size = sizeof(struct ifmibdata);
+ static int32_t data_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL };
+ data_option[4] = net_row;
+ sysctl(data_option, 6, data, &size, NULL, 0);
+}
+
+static inline void network_init(struct network* net, char* ifname) {
+ memset(net, 0, sizeof(struct network));
+
+ static int count_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
+ uint32_t interface_count = 0;
+ size_t size = sizeof(uint32_t);
+ sysctl(count_option, 5, &interface_count, &size, NULL, 0);
+
+ for (int i = 0; i < interface_count; i++) {
+ ifdata(i, &net->data);
+ if (strcmp(net->data.ifmd_name, ifname) == 0) {
+ net->row = i;
+ break;
+ }
+ }
+}
+
+static inline void network_update(struct network* net) {
+ gettimeofday(&net->tv_n, NULL);
+ timersub(&net->tv_n, &net->tv_nm1, &net->tv_delta);
+ net->tv_nm1 = net->tv_n;
+
+ uint64_t ibytes_nm1 = net->data.ifmd_data.ifi_ibytes;
+ uint64_t obytes_nm1 = net->data.ifmd_data.ifi_obytes;
+ ifdata(net->row, &net->data);
+
+ double time_scale = (net->tv_delta.tv_sec + 1e-6*net->tv_delta.tv_usec);
+ if (time_scale < 1e-6 || time_scale > 1e2) return;
+ double delta_ibytes = (double)(net->data.ifmd_data.ifi_ibytes - ibytes_nm1)
+ / time_scale;
+ double delta_obytes = (double)(net->data.ifmd_data.ifi_obytes - obytes_nm1)
+ / time_scale;
+
+ double exponent_ibytes = log10(delta_ibytes);
+ double exponent_obytes = log10(delta_obytes);
+
+ if (exponent_ibytes < 3) {
+ net->down_unit = UNIT_BPS;
+ net->down = delta_ibytes;
+ } else if (exponent_ibytes < 6) {
+ net->down_unit = UNIT_KBPS;
+ net->down = delta_ibytes / 1000.0;
+ } else if (exponent_ibytes < 9) {
+ net->down_unit = UNIT_MBPS;
+ net->down = delta_ibytes / 1000000.0;
+ }
+
+ if (exponent_obytes < 3) {
+ net->up_unit = UNIT_BPS;
+ net->up = delta_obytes;
+ } else if (exponent_obytes < 6) {
+ net->up_unit = UNIT_KBPS;
+ net->up = delta_obytes / 1000.0;
+ } else if (exponent_obytes < 9) {
+ net->up_unit = UNIT_MBPS;
+ net->up = delta_obytes / 1000000.0;
+ }
+}
diff --git a/.config/sketchybar/helpers/event_providers/network_load/network_load.c b/.config/sketchybar/helpers/event_providers/network_load/network_load.c
new file mode 100644
index 0000000..06afe95
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/network_load/network_load.c
@@ -0,0 +1,42 @@
+#include <unistd.h>
+#include "network.h"
+#include "../sketchybar.h"
+
+int main (int argc, char** argv) {
+ float update_freq;
+ if (argc < 4 || (sscanf(argv[3], "%f", &update_freq) != 1)) {
+ printf("Usage: %s \"<interface>\" \"<event-name>\" \"<event_freq>\"\n", argv[0]);
+ exit(1);
+ }
+
+ alarm(0);
+ // Setup the event in sketchybar
+ char event_message[512];
+ snprintf(event_message, 512, "--add event '%s'", argv[2]);
+ sketchybar(event_message);
+
+ struct network network;
+ network_init(&network, argv[1]);
+ char trigger_message[512];
+ for (;;) {
+ // Acquire new info
+ network_update(&network);
+
+ // Prepare the event message
+ snprintf(trigger_message,
+ 512,
+ "--trigger '%s' upload='%03d%s' download='%03d%s'",
+ argv[2],
+ network.up,
+ unit_str[network.up_unit],
+ network.down,
+ unit_str[network.down_unit]);
+
+ // Trigger the event
+ sketchybar(trigger_message);
+
+ // Wait
+ usleep(update_freq * 1000000);
+ }
+ return 0;
+}
diff --git a/.config/sketchybar/helpers/event_providers/sketchybar.h b/.config/sketchybar/helpers/event_providers/sketchybar.h
new file mode 100644
index 0000000..b194d8a
--- /dev/null
+++ b/.config/sketchybar/helpers/event_providers/sketchybar.h
@@ -0,0 +1,124 @@
+#pragma once
+
+#include <bootstrap.h>
+#include <mach/arm/kern_return.h>
+#include <mach/mach.h>
+#include <mach/mach_port.h>
+#include <mach/message.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.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;
+};
+
+static mach_port_t g_mach_port = 0;
+
+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;
+ }
+
+ char *name = getenv("BAR_NAME");
+ if (!name)
+ name = "sketchybar";
+ uint32_t lookup_len = 16 + strlen(name);
+
+ char buffer[lookup_len];
+ snprintf(buffer, lookup_len, "git.felix.%s", name);
+
+ mach_port_t port;
+ if (bootstrap_look_up(bs_port, buffer, &port) != KERN_SUCCESS)
+ return 0;
+ return port;
+}
+
+static inline bool mach_send_message(mach_port_t port, char *message,
+ uint32_t len) {
+ if (!message || !port) {
+ return false;
+ }
+
+ 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;
+
+ kern_return_t err =
+ mach_msg(&msg.header, MACH_SEND_MSG, sizeof(struct mach_message), 0,
+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+ return err == KERN_SUCCESS;
+}
+
+static inline uint32_t format_message(char *message, char *formatted_message) {
+ // This is not actually robust, switch to stack based messaging.
+ char outer_quote = 0;
+ uint32_t caret = 0;
+ uint32_t message_length = strlen(message) + 1;
+ for (int i = 0; i < message_length; ++i) {
+ if (message[i] == '"' || message[i] == '\'') {
+ if (outer_quote && outer_quote == message[i])
+ outer_quote = 0;
+ else if (!outer_quote)
+ outer_quote = message[i];
+ continue;
+ }
+ formatted_message[caret] = message[i];
+ if (message[i] == ' ' && !outer_quote)
+ formatted_message[caret] = '\0';
+ caret++;
+ }
+
+ if (caret > 0 && formatted_message[caret] == '\0' &&
+ formatted_message[caret - 1] == '\0') {
+ caret--;
+ }
+ formatted_message[caret] = '\0';
+ return caret + 1;
+}
+
+static inline void sketchybar(char *message) {
+ char formatted_message[strlen(message) + 2];
+ uint32_t length = format_message(message, formatted_message);
+ if (!length)
+ return;
+
+ if (!g_mach_port)
+ g_mach_port = mach_get_bs_port();
+ if (!mach_send_message(g_mach_port, formatted_message, length)) {
+ g_mach_port = mach_get_bs_port();
+ if (!mach_send_message(g_mach_port, formatted_message, length)) {
+ // No sketchybar instance running, exit.
+ exit(0);
+ }
+ }
+}
diff --git a/.config/sketchybar/helpers/init.lua b/.config/sketchybar/helpers/init.lua
new file mode 100644
index 0000000..351531a
--- /dev/null
+++ b/.config/sketchybar/helpers/init.lua
@@ -0,0 +1,4 @@
+-- Add the sketchybar module to the package cpath
+package.cpath = package.cpath .. ";/Users/" .. os.getenv("USER") .. "/.local/share/sketchybar_lua/?.so"
+
+os.execute("(cd helpers && make)")
diff --git a/.config/sketchybar/helpers/install.sh b/.config/sketchybar/helpers/install.sh
new file mode 100755
index 0000000..cdde4ad
--- /dev/null
+++ b/.config/sketchybar/helpers/install.sh
@@ -0,0 +1,17 @@
+# Packages
+brew install lua
+brew install switchaudio-osx
+brew install nowplaying-cli
+
+brew tap FelixKratz/formulae
+brew install sketchybar
+
+# Fonts
+brew install --cask sf-symbols
+brew install --cask homebrew/cask-fonts/font-sf-mono
+brew install --cask homebrew/cask-fonts/font-sf-pro
+
+curl -L https://github.com/kvndrsslr/sketchybar-app-font/releases/download/v2.0.5/sketchybar-app-font.ttf -o $HOME/Library/Fonts/sketchybar-app-font.ttf
+
+# SbarLua
+(git clone https://github.com/FelixKratz/SbarLua.git /tmp/SbarLua && cd /tmp/SbarLua/ && make install && rm -rf /tmp/SbarLua/)
diff --git a/.config/sketchybar/helpers/makefile b/.config/sketchybar/helpers/makefile
new file mode 100644
index 0000000..3246108
--- /dev/null
+++ b/.config/sketchybar/helpers/makefile
@@ -0,0 +1,3 @@
+all:
+ (cd event_providers && $(MAKE)) >/dev/null
+ (cd menus && $(MAKE)) >/dev/null
diff --git a/.config/sketchybar/helpers/menus/makefile b/.config/sketchybar/helpers/menus/makefile
new file mode 100644
index 0000000..0cb454e
--- /dev/null
+++ b/.config/sketchybar/helpers/menus/makefile
@@ -0,0 +1,5 @@
+bin/menus: menus.c | bin
+ clang -std=c99 -O3 -F/System/Library/PrivateFrameworks/ -framework Carbon -framework SkyLight $< -o $@
+
+bin:
+ mkdir bin
diff --git a/.config/sketchybar/helpers/menus/menus.c b/.config/sketchybar/helpers/menus/menus.c
new file mode 100644
index 0000000..2e77822
--- /dev/null
+++ b/.config/sketchybar/helpers/menus/menus.c
@@ -0,0 +1,248 @@
+#include <Carbon/Carbon.h>
+
+void ax_init() {
+ const void *keys[] = { kAXTrustedCheckOptionPrompt };
+ const void *values[] = { kCFBooleanTrue };
+
+ CFDictionaryRef options;
+ options = CFDictionaryCreate(kCFAllocatorDefault,
+ keys,
+ values,
+ sizeof(keys) / sizeof(*keys),
+ &kCFCopyStringDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks );
+
+ bool trusted = AXIsProcessTrustedWithOptions(options);
+ CFRelease(options);
+ if (!trusted) exit(1);
+}
+
+void ax_perform_click(AXUIElementRef element) {
+ if (!element) return;
+ AXUIElementPerformAction(element, kAXCancelAction);
+ usleep(150000);
+ AXUIElementPerformAction(element, kAXPressAction);
+}
+
+CFStringRef ax_get_title(AXUIElementRef element) {
+ CFTypeRef title = NULL;
+ AXError error = AXUIElementCopyAttributeValue(element,
+ kAXTitleAttribute,
+ &title );
+
+ if (error != kAXErrorSuccess) return NULL;
+ return title;
+}
+
+void ax_select_menu_option(AXUIElementRef app, int id) {
+ AXUIElementRef menubars_ref = NULL;
+ CFArrayRef children_ref = NULL;
+
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXMenuBarAttribute,
+ (CFTypeRef*)&menubars_ref);
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(menubars_ref,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+ if (id < count) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, id);
+ ax_perform_click(item);
+ }
+ if (children_ref) CFRelease(children_ref);
+ }
+ if (menubars_ref) CFRelease(menubars_ref);
+ }
+}
+
+void ax_print_menu_options(AXUIElementRef app) {
+ AXUIElementRef menubars_ref = NULL;
+ CFTypeRef menubar = NULL;
+ CFArrayRef children_ref = NULL;
+
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXMenuBarAttribute,
+ (CFTypeRef*)&menubars_ref);
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(menubars_ref,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+
+ for (int i = 1; i < count; i++) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
+ CFTypeRef title = ax_get_title(item);
+
+ if (title) {
+ uint32_t buffer_len = 2*CFStringGetLength(title);
+ char buffer[2*CFStringGetLength(title)];
+ CFStringGetCString(title, buffer, buffer_len, kCFStringEncodingUTF8);
+ printf("%s\n", buffer);
+ CFRelease(title);
+ }
+ }
+ }
+ if (menubars_ref) CFRelease(menubars_ref);
+ if (children_ref) CFRelease(children_ref);
+ }
+}
+
+AXUIElementRef ax_get_extra_menu_item(char* alias) {
+ pid_t pid = 0;
+ CGRect bounds = CGRectNull;
+ CFArrayRef window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll,
+ kCGNullWindowID );
+ char owner_buffer[256];
+ char name_buffer[256];
+ char buffer[512];
+ int window_count = CFArrayGetCount(window_list);
+ for (int i = 0; i < window_count; ++i) {
+ CFDictionaryRef dictionary = CFArrayGetValueAtIndex(window_list, i);
+ if (!dictionary) continue;
+
+ CFStringRef owner_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowOwnerName);
+
+ CFNumberRef owner_pid_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowOwnerPID);
+
+ CFStringRef name_ref = CFDictionaryGetValue(dictionary, kCGWindowName);
+ CFNumberRef layer_ref = CFDictionaryGetValue(dictionary, kCGWindowLayer);
+ CFDictionaryRef bounds_ref = CFDictionaryGetValue(dictionary,
+ kCGWindowBounds);
+
+ if (!name_ref || !owner_ref || !owner_pid_ref || !layer_ref || !bounds_ref)
+ continue;
+
+ long long int layer = 0;
+ CFNumberGetValue(layer_ref, CFNumberGetType(layer_ref), &layer);
+ uint64_t owner_pid = 0;
+ CFNumberGetValue(owner_pid_ref,
+ CFNumberGetType(owner_pid_ref),
+ &owner_pid );
+
+ if (layer != 0x19) continue;
+ bounds = CGRectNull;
+ if (!CGRectMakeWithDictionaryRepresentation(bounds_ref, &bounds)) continue;
+ CFStringGetCString(owner_ref,
+ owner_buffer,
+ sizeof(owner_buffer),
+ kCFStringEncodingUTF8);
+
+ CFStringGetCString(name_ref,
+ name_buffer,
+ sizeof(name_buffer),
+ kCFStringEncodingUTF8);
+ snprintf(buffer, sizeof(buffer), "%s,%s", owner_buffer, name_buffer);
+
+ if (strcmp(buffer, alias) == 0) {
+ pid = owner_pid;
+ break;
+ }
+ }
+ CFRelease(window_list);
+ if (!pid) return NULL;
+
+ AXUIElementRef app = AXUIElementCreateApplication(pid);
+ if (!app) return NULL;
+ AXUIElementRef result = NULL;
+ CFTypeRef extras = NULL;
+ CFArrayRef children_ref = NULL;
+ AXError error = AXUIElementCopyAttributeValue(app,
+ kAXExtrasMenuBarAttribute,
+ &extras );
+ if (error == kAXErrorSuccess) {
+ error = AXUIElementCopyAttributeValue(extras,
+ kAXVisibleChildrenAttribute,
+ (CFTypeRef*)&children_ref );
+
+ if (error == kAXErrorSuccess) {
+ uint32_t count = CFArrayGetCount(children_ref);
+ for (uint32_t i = 0; i < count; i++) {
+ AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
+ CFTypeRef position_ref = NULL;
+ CFTypeRef size_ref = NULL;
+ AXUIElementCopyAttributeValue(item, kAXPositionAttribute,
+ &position_ref );
+ AXUIElementCopyAttributeValue(item, kAXSizeAttribute,
+ &size_ref );
+ if (!position_ref || !size_ref) continue;
+
+ CGPoint position = CGPointZero;
+ AXValueGetValue(position_ref, kAXValueCGPointType, &position);
+ CGSize size = CGSizeZero;
+ AXValueGetValue(size_ref, kAXValueCGSizeType, &size);
+ CFRelease(position_ref);
+ CFRelease(size_ref);
+ // The offset is exactly 8 on macOS Sonoma...
+ // printf("%f %f\n", position.x, bounds.origin.x);
+ if (error == kAXErrorSuccess
+ && fabs(position.x - bounds.origin.x) <= 10) {
+ result = item;
+ break;
+ }
+ }
+ }
+ }
+
+ CFRelease(app);
+ return result;
+}
+
+extern int SLSMainConnectionID();
+extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
+extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
+extern void SLSSetMenuBarInsetAndAlpha(int cid, double u1, double u2, float alpha);
+void ax_select_menu_extra(char* alias) {
+ AXUIElementRef item = ax_get_extra_menu_item(alias);
+ if (!item) return;
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
+ SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, true);
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
+ ax_perform_click(item);
+ SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, false);
+ SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 1.0);
+ CFRelease(item);
+}
+
+extern void _SLPSGetFrontProcess(ProcessSerialNumber* psn);
+extern void SLSGetConnectionIDForPSN(int cid, ProcessSerialNumber* psn, int* cid_out);
+extern void SLSConnectionGetPID(int cid, pid_t* pid_out);
+AXUIElementRef ax_get_front_app() {
+ ProcessSerialNumber psn;
+ _SLPSGetFrontProcess(&psn);
+ int target_cid;
+ SLSGetConnectionIDForPSN(SLSMainConnectionID(), &psn, &target_cid);
+
+ pid_t pid;
+ SLSConnectionGetPID(target_cid, &pid);
+ return AXUIElementCreateApplication(pid);
+}
+
+int main (int argc, char **argv) {
+ if (argc == 1) {
+ printf("Usage: %s [-l | -s id/alias ]\n", argv[0]);
+ exit(0);
+ }
+ ax_init();
+ if (strcmp(argv[1], "-l") == 0) {
+ AXUIElementRef app = ax_get_front_app();
+ if (!app) return 1;
+ ax_print_menu_options(app);
+ CFRelease(app);
+ } else if (argc == 3 && strcmp(argv[1], "-s") == 0) {
+ int id = 0;
+ if (sscanf(argv[2], "%d", &id) == 1) {
+ AXUIElementRef app = ax_get_front_app();
+ if (!app) return 1;
+ ax_select_menu_option(app, id);
+ CFRelease(app);
+ } else ax_select_menu_extra(argv[2]);
+ }
+ return 0;
+}
diff --git a/.config/sketchybar/icons.lua b/.config/sketchybar/icons.lua
new file mode 100644
index 0000000..844b35c
--- /dev/null
+++ b/.config/sketchybar/icons.lua
@@ -0,0 +1,92 @@
+local settings = require("settings")
+
+local icons = {
+ sf_symbols = {
+ plus = "􀅼",
+ loading = "􀖇",
+ apple = "􀣺",
+ gear = "􀍟",
+ cpu = "􀫥",
+ clipboard = "􀉄",
+
+ switch = {
+ on = "􁏮",
+ off = "􁏯",
+ },
+ volume = {
+ _100 = "􀊩",
+ _66 = "􀊧",
+ _33 = "􀊥",
+ _10 = "􀊡",
+ _0 = "􀊣",
+ },
+ battery = {
+ _100 = "􀛨",
+ _75 = "􀺸",
+ _50 = "􀺶",
+ _25 = "􀛩",
+ _0 = "􀛪",
+ charging = "􀢋",
+ },
+ wifi = {
+ upload = "􀄨",
+ download = "􀄩",
+ connected = "􀙇",
+ disconnected = "􀙈",
+ router = "􁓤",
+ },
+ media = {
+ back = "􀊊",
+ forward = "􀊌",
+ play_pause = "􀊈",
+ },
+ },
+
+ -- Alternative NerdFont icons
+ nerdfont = {
+ plus = "",
+ loading = "",
+ apple = "",
+ gear = "",
+ cpu = "",
+ clipboard = "Missing Icon",
+
+ switch = {
+ on = "󱨥",
+ off = "󱨦",
+ },
+ volume = {
+ _100 = "",
+ _66 = "",
+ _33 = "",
+ _10 = "",
+ _0 = "",
+ },
+ battery = {
+ _100 = "",
+ _75 = "",
+ _50 = "",
+ _25 = "",
+ _0 = "",
+ charging = "",
+ },
+ wifi = {
+ upload = "",
+ download = "",
+ connected = "󰖩",
+ disconnected = "󰖪",
+ router = "Missing Icon",
+ },
+ media = {
+ back = "",
+ forward = "",
+ play_pause = "",
+ },
+ },
+}
+
+if not (settings.icons == "NerdFont") then
+ return icons.sf_symbols
+else
+ return icons.nerdfont
+end
diff --git a/.config/sketchybar/init.lua b/.config/sketchybar/init.lua
new file mode 100644
index 0000000..e1bf892
--- /dev/null
+++ b/.config/sketchybar/init.lua
@@ -0,0 +1,16 @@
+-- Require the sketchybar module
+sbar = require("sketchybar")
+
+-- Set the bar name, if you are using another bar instance than sketchybar
+-- sbar.set_bar_name("bottom_bar")
+
+-- Bundle the entire initial configuration into a single message to sketchybar
+sbar.begin_config()
+require("bar")
+require("default")
+require("items")
+sbar.end_config()
+
+-- Run the event loop of the sketchybar module (without this there will be no
+-- callback functions executed in the lua module)
+sbar.event_loop()
diff --git a/.config/sketchybar/items/apple.lua b/.config/sketchybar/items/apple.lua
new file mode 100644
index 0000000..00e9f44
--- /dev/null
+++ b/.config/sketchybar/items/apple.lua
@@ -0,0 +1,38 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+-- Padding item required because of bracket
+sbar.add("item", { width = 5 })
+
+local apple = sbar.add("item", {
+ icon = {
+ font = { size = 16.0 },
+ string = icons.apple,
+ padding_right = 8,
+ padding_left = 8,
+ },
+ label = { drawing = false },
+ background = {
+ -- was bg2
+ color = settings.apple_background,
+ border_color = settings.apple_border,
+ border_width = 1,
+ },
+ padding_left = 1,
+ padding_right = 1,
+ click_script = "$CONFIG_DIR/helpers/menus/bin/menus -s 0",
+})
+
+-- Double border for apple using a single item bracket
+sbar.add("bracket", { apple.name }, {
+ background = {
+ color = colors.transparent,
+ height = 30,
+ border_color = colors.grey,
+ },
+})
+
+-- Padding item required because of bracket
+sbar.add("item", { width = 7 })
diff --git a/.config/sketchybar/items/calendar.lua b/.config/sketchybar/items/calendar.lua
new file mode 100644
index 0000000..36ca093
--- /dev/null
+++ b/.config/sketchybar/items/calendar.lua
@@ -0,0 +1,50 @@
+local settings = require("settings")
+local colors = require("colors")
+local sbar = require("sketchybar")
+
+-- Padding item required because of bracket
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+local cal = sbar.add("item", {
+ icon = {
+ color = colors.white,
+ padding_left = 8,
+ font = {
+ style = settings.font.style_map["Black"],
+ size = 12.0,
+ },
+ },
+ label = {
+ color = colors.white,
+ padding_right = 8,
+ width = 49,
+ align = "right",
+ font = { family = settings.font.numbers },
+ },
+ position = "right",
+ update_freq = 30,
+ padding_left = 1,
+ padding_right = 1,
+ background = {
+ -- changes the color of background widget
+ color = settings.calendar_background,
+ border_color = settings.calendar_border,
+ border_width = 1,
+ },
+})
+
+-- Double border for calendar using a single item bracket
+sbar.add("bracket", { cal.name }, {
+ background = {
+ color = colors.transparent,
+ height = 30,
+ border_color = colors.grey,
+ },
+})
+
+-- Padding item required because of bracket
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+cal:subscribe({ "forced", "routine", "system_woke" }, function(env)
+ cal:set({ icon = os.date("%a. %d %b."), label = os.date("%H:%M") })
+end)
diff --git a/.config/sketchybar/items/front_app.lua b/.config/sketchybar/items/front_app.lua
new file mode 100644
index 0000000..d7dab4b
--- /dev/null
+++ b/.config/sketchybar/items/front_app.lua
@@ -0,0 +1,22 @@
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+local front_app = sbar.add("item", "front_app", {
+ display = "active",
+ icon = { drawing = false },
+ label = {
+ font = {
+ style = settings.font.style_map["Black"],
+ size = 12.0,
+ },
+ },
+ updates = true,
+})
+
+front_app:subscribe("front_app_switched", function(env)
+ front_app:set({ label = { string = env.INFO } })
+end)
+
+front_app:subscribe("mouse.clicked", function(env)
+ sbar.trigger("swap_menus_and_spaces")
+end)
diff --git a/.config/sketchybar/items/init.lua b/.config/sketchybar/items/init.lua
new file mode 100644
index 0000000..dad59fa
--- /dev/null
+++ b/.config/sketchybar/items/init.lua
@@ -0,0 +1,7 @@
+require("items.apple")
+require("items.menus")
+require("items.spaces")
+require("items.front_app")
+require("items.calendar")
+require("items.widgets")
+require("items.media")
diff --git a/.config/sketchybar/items/media.lua b/.config/sketchybar/items/media.lua
new file mode 100644
index 0000000..8a9ef7d
--- /dev/null
+++ b/.config/sketchybar/items/media.lua
@@ -0,0 +1,122 @@
+local icons = require("icons")
+local colors = require("colors")
+local sbar = require("sketchybar")
+
+local whitelist = { ["Spotify"] = true, ["Music"] = true, ["Sound Cloud"] = true }
+
+local media_cover = sbar.add("item", {
+ position = "right",
+ background = {
+ image = {
+ string = "media.artwork",
+ scale = 0.85,
+ },
+ color = colors.transparent,
+ },
+ label = { drawing = false },
+ icon = { drawing = false },
+ drawing = false,
+ updates = true,
+ popup = {
+ align = "center",
+ horizontal = true,
+ },
+})
+
+local media_artist = sbar.add("item", {
+ position = "right",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ width = 0,
+ icon = { drawing = false },
+ label = {
+ width = 0,
+ font = { size = 9 },
+ color = colors.with_alpha(colors.white, 0.6),
+ max_chars = 18,
+ y_offset = 6,
+ },
+})
+
+local media_title = sbar.add("item", {
+ position = "right",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ icon = { drawing = false },
+ label = {
+ font = { size = 11 },
+ width = 0,
+ max_chars = 16,
+ y_offset = -5,
+ },
+})
+
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.back },
+ label = { drawing = false },
+ click_script = "nowplaying-cli previous",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.play_pause },
+ label = { drawing = false },
+ click_script = "nowplaying-cli togglePlayPause",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.forward },
+ label = { drawing = false },
+ click_script = "nowplaying-cli next",
+})
+
+local interrupt = 0
+local function animate_detail(detail)
+ if not detail then
+ interrupt = interrupt - 1
+ end
+ if interrupt > 0 and not detail then
+ return
+ end
+
+ sbar.animate("tanh", 30, function()
+ media_artist:set({ label = { width = detail and "dynamic" or 0 } })
+ media_title:set({ label = { width = detail and "dynamic" or 0 } })
+ end)
+end
+
+media_cover:subscribe("media_change", function(env)
+ if whitelist[env.INFO.app] then
+ local drawing = (env.INFO.state == "playing")
+ media_artist:set({ drawing = drawing, label = env.INFO.artist })
+ media_title:set({ drawing = drawing, label = env.INFO.title })
+ media_cover:set({ drawing = drawing })
+
+ if drawing then
+ animate_detail(true)
+ interrupt = interrupt + 1
+ sbar.delay(5, animate_detail)
+ else
+ media_cover:set({ popup = { drawing = false } })
+ end
+ end
+end)
+
+media_cover:subscribe("mouse.entered", function(env)
+ interrupt = interrupt + 1
+ animate_detail(true)
+end)
+
+media_cover:subscribe("mouse.exited", function(env)
+ animate_detail(false)
+end)
+
+media_cover:subscribe("mouse.clicked", function(env)
+ media_cover:set({ popup = { drawing = "toggle" } })
+end)
+
+media_title:subscribe("mouse.exited.global", function(env)
+ media_cover:set({ popup = { drawing = false } })
+end)
diff --git a/.config/sketchybar/items/menus.lua b/.config/sketchybar/items/menus.lua
new file mode 100644
index 0000000..66cdd4a
--- /dev/null
+++ b/.config/sketchybar/items/menus.lua
@@ -0,0 +1,78 @@
+local colors = require("colors")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+local menu_watcher = sbar.add("item", {
+ drawing = false,
+ updates = false,
+})
+local space_menu_swap = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+sbar.add("event", "swap_menus_and_spaces")
+
+local max_items = 15
+local menu_items = {}
+for i = 1, max_items, 1 do
+ local menu = sbar.add("item", "menu." .. i, {
+ padding_left = settings.paddings,
+ padding_right = settings.paddings,
+ drawing = false,
+ icon = { drawing = false },
+ label = {
+ font = {
+ style = settings.font.style_map[i == 1 and "Heavy" or "Semibold"],
+ },
+ padding_left = 6,
+ padding_right = 6,
+ },
+ click_script = "$CONFIG_DIR/helpers/menus/bin/menus -s " .. i,
+ })
+
+ menu_items[i] = menu
+end
+
+sbar.add("bracket", { "/menu\\..*/" }, {
+ background = { color = colors.bg1 },
+})
+
+local menu_padding = sbar.add("item", "menu.padding", {
+ drawing = false,
+ width = 5,
+})
+
+local function update_menus(env)
+ sbar.exec("$CONFIG_DIR/helpers/menus/bin/menus -l", function(menus)
+ sbar.set("/menu\\..*/", { drawing = false })
+ menu_padding:set({ drawing = true })
+ id = 1
+ for menu in string.gmatch(menus, "[^\r\n]+") do
+ if id < max_items then
+ menu_items[id]:set({ label = menu, drawing = true })
+ else
+ break
+ end
+ id = id + 1
+ end
+ end)
+end
+
+menu_watcher:subscribe("front_app_switched", update_menus)
+
+space_menu_swap:subscribe("swap_menus_and_spaces", function(env)
+ local drawing = menu_items[1]:query().geometry.drawing == "on"
+ if drawing then
+ menu_watcher:set({ updates = false })
+ sbar.set("/menu\\..*/", { drawing = false })
+ sbar.set("/space\\..*/", { drawing = true })
+ sbar.set("front_app", { drawing = true })
+ else
+ menu_watcher:set({ updates = true })
+ sbar.set("/space\\..*/", { drawing = false })
+ sbar.set("front_app", { drawing = false })
+ update_menus()
+ end
+end)
+
+return menu_watcher
diff --git a/.config/sketchybar/items/spaces.lua b/.config/sketchybar/items/spaces.lua
new file mode 100644
index 0000000..100b050
--- /dev/null
+++ b/.config/sketchybar/items/spaces.lua
@@ -0,0 +1,186 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+local app_icons = require("helpers.app_icons")
+local sbar = require("sketchybar")
+
+local spaces = {}
+
+for i = 1, 10, 1 do
+ local space = sbar.add("space", "space." .. i, {
+ space = i,
+ icon = {
+ font = { family = settings.font.numbers },
+ string = i,
+ padding_left = 15,
+ padding_right = 8,
+ color = colors.white,
+ -- the highlighter color
+ highlight_color = settings.spaces_highlight,
+ },
+ label = {
+ padding_right = 20,
+ -- icon coloring for spaces
+ color = settings.spaces_icon,
+ highlight_color = colors.white,
+ font = "sketchybar-app-font:Regular:16.0",
+ y_offset = -1,
+ },
+ padding_right = 1,
+ padding_left = 1,
+ background = {
+ -- this is bg color for spaces
+ color = settings.spaces_background,
+ border_width = 1,
+ height = 26,
+ border_color = settings.spaces_border,
+ },
+ popup = { background = { border_width = 5, border_color = colors.black } },
+ })
+
+ spaces[i] = space
+
+ -- Single item bracket for space items to achieve double border on highlight
+ local space_bracket = sbar.add("bracket", { space.name }, {
+ background = {
+ color = colors.transparent,
+ border_color = colors.bg2,
+ height = 28,
+ border_width = 2,
+ },
+ })
+
+ -- Padding space
+ sbar.add("space", "space.padding." .. i, {
+ space = i,
+ script = "",
+ width = settings.group_paddings,
+ })
+
+ local space_popup = sbar.add("item", {
+ position = "popup." .. space.name,
+ padding_left = 5,
+ padding_right = 0,
+ background = {
+ drawing = true,
+ image = {
+ corner_radius = 9,
+ scale = 0.2,
+ },
+ },
+ })
+
+ space:subscribe("space_change", function(env)
+ local selected = env.SELECTED == "true"
+ local color = selected and colors.grey or colors.bg2
+ space:set({
+ icon = { highlight = selected },
+ label = { highlight = selected },
+ background = { border_color = selected and colors.black or colors.bg2 },
+ })
+ space_bracket:set({
+ background = { border_color = selected and colors.grey or colors.bg2 },
+ })
+ end)
+
+ space:subscribe("mouse.clicked", function(env)
+ if env.BUTTON == "other" then
+ space_popup:set({ background = { image = "space." .. env.SID } })
+ space:set({ popup = { drawing = "toggle" } })
+ else
+ local op = (env.BUTTON == "right") and "--destroy" or "--focus"
+ os.execute("yabai -m space " .. op .. " " .. env.SID)
+ -- sbar.exec() is acting weird
+ -- sbar.exec("yabai -m space " .. op .. " " .. env.SID)
+ end
+ end)
+
+ space:subscribe("mouse.exited", function(_)
+ space:set({ popup = { drawing = false } })
+ end)
+end
+
+local space_window_observer = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local spaces_indicator = sbar.add("item", {
+ padding_left = -3,
+ padding_right = 0,
+ icon = {
+ padding_left = 8,
+ padding_right = 9,
+ -- changed coloring of selected app icon
+ color = settings.spaces_selected,
+ string = icons.switch.on,
+ },
+ label = {
+ width = 0,
+ padding_left = 0,
+ padding_right = 8,
+ string = "Spaces",
+ -- bg1
+ color = colors.bg1,
+ },
+ background = {
+ -- grey
+ color = colors.with_alpha(colors.grey, 0.0),
+ border_color = colors.with_alpha(colors.bg1, 0.0),
+ },
+})
+
+space_window_observer:subscribe("space_windows_change", function(env)
+ local icon_line = ""
+ local no_app = true
+ for app, count in pairs(env.INFO.apps) do
+ no_app = false
+ local lookup = app_icons[app]
+ local icon = ((lookup == nil) and app_icons["default"] or lookup)
+ icon_line = icon_line .. " " .. icon
+ end
+
+ if no_app then
+ icon_line = " —"
+ end
+ sbar.animate("tanh", 10, function()
+ spaces[env.INFO.space]:set({ label = icon_line })
+ end)
+end)
+
+spaces_indicator:subscribe("swap_menus_and_spaces", function(env)
+ local currently_on = spaces_indicator:query().icon.value == icons.switch.on
+ spaces_indicator:set({
+ icon = currently_on and icons.switch.off or icons.switch.on,
+ })
+end)
+
+spaces_indicator:subscribe("mouse.entered", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces_indicator:set({
+ background = {
+ color = { alpha = 1.0 },
+ border_color = { alpha = 1.0 },
+ },
+ icon = { color = colors.bg1 },
+ label = { width = "dynamic" },
+ })
+ end)
+end)
+
+spaces_indicator:subscribe("mouse.exited", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces_indicator:set({
+ background = {
+ color = { alpha = 0.0 },
+ border_color = { alpha = 0.0 },
+ },
+ icon = { color = colors.grey },
+ label = { width = 0 },
+ })
+ end)
+end)
+
+spaces_indicator:subscribe("mouse.clicked", function(env)
+ sbar.trigger("swap_menus_and_spaces")
+end)
diff --git a/.config/sketchybar/items/widgets/battery.lua b/.config/sketchybar/items/widgets/battery.lua
new file mode 100644
index 0000000..13356f1
--- /dev/null
+++ b/.config/sketchybar/items/widgets/battery.lua
@@ -0,0 +1,117 @@
+local icons = require("icons")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+function os.capture(cmd, raw)
+ local file = assert(io.popen(cmd, "r"))
+ local output = assert(file:read("*a"))
+ file:close()
+
+ if raw then
+ return output
+ end
+
+ output = string.gsub(output, "^%s+", "")
+ output = string.gsub(output, "%s+$", "")
+ output = string.gsub(output, "[\n\r]+", "")
+
+ return output
+end
+
+local battery = sbar.add("item", "widgets.battery", {
+ position = "right",
+ icon = {
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 19.0,
+ },
+ },
+ label = { font = { family = settings.font.numbers } },
+ update_freq = 180,
+ popup = { align = "center" },
+})
+
+local remaining_time = sbar.add("item", {
+ position = "popup." .. battery.name,
+ icon = {
+ string = "Time remaining:",
+ width = 100,
+ align = "left",
+ },
+ label = {
+ string = "??:??h",
+ width = 100,
+ align = "right",
+ },
+})
+
+-- TODO: This is where the battery widget issue is occuring...
+local function battery_update()
+ Color = settings.batt_color_default
+
+ local batt_info = os.capture("pmset -g batt", false)
+ local icon = "!"
+ local label = "?"
+
+ if batt_info:find("AC Power") then
+ icon = icons.battery.charging
+ else
+ local found, _, charge = batt_info:find("(%d+)%%")
+ if found then
+ charge = tonumber(charge)
+ label = charge .. "%"
+ end
+
+ if found and charge > 80 then
+ icon = icons.battery._100
+ elseif found and charge > 60 then
+ icon = icons.battery._75
+ elseif found and charge > 40 then
+ icon = icons.battery._50
+ elseif found and charge > 20 then
+ icon = icons.battery._25
+ Color = settings.batt_color_25
+ else
+ icon = icons.battery._0
+ Color = settings.batt_color_0
+ end
+ end
+ -- TODO: Add in charging percentage
+ local lead = ""
+ if label == "?" then
+ label = "W"
+ end
+
+ battery:set({
+ icon = {
+ string = icon,
+ color = Color,
+ },
+ label = { string = lead .. label },
+ })
+end
+
+battery:subscribe({ "routine", "power_source_change", "system_woke" }, battery_update)
+
+battery:subscribe("mouse.clicked", function(env)
+ local drawing = battery:query().popup.drawing
+ battery:set({ popup = { drawing = "toggle" } })
+
+ if drawing == "off" then
+ sbar.exec("pmset -g batt", function(batt_info)
+ local found, _, remaining = batt_info:find(" (%d+:%d+) remaining")
+ local label = found and remaining .. "h" or "No estimate"
+ remaining_time:set({ label = label })
+ end)
+ end
+end)
+
+sbar.add("bracket", "widgets.battery.bracket", { battery.name }, {
+ -- changes color of widget background
+ background = { color = settings.batt_background },
+})
+
+sbar.add("item", "widgets.battery.padding", {
+ position = "right",
+ width = settings.group_paddings,
+})
diff --git a/.config/sketchybar/items/widgets/cpu.lua b/.config/sketchybar/items/widgets/cpu.lua
new file mode 100644
index 0000000..89b3647
--- /dev/null
+++ b/.config/sketchybar/items/widgets/cpu.lua
@@ -0,0 +1,71 @@
+local icons = require("icons")
+local colors = require("colors")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+-- Execute the event provider binary which provides the event "cpu_update" for
+-- the cpu load data, which is fired every 2.0 seconds.
+sbar.exec("killall cpu_load >/dev/null; $CONFIG_DIR/helpers/event_providers/cpu_load/bin/cpu_load cpu_update 2.0")
+
+local cpu = sbar.add("graph", "widgets.cpu", 42, {
+ position = "right",
+ graph = { color = colors.blue },
+ background = {
+ height = 22,
+ color = { alpha = 0 },
+ border_color = { alpha = 0 },
+ drawing = true,
+ },
+ icon = { string = icons.cpu },
+ label = {
+ string = "cpu ??%",
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ align = "right",
+ padding_right = 0,
+ width = 0,
+ y_offset = 4,
+ },
+ padding_right = settings.paddings + 6,
+})
+
+cpu:subscribe("cpu_update", function(env)
+ -- Also available: env.user_load, env.sys_load
+ local load = tonumber(env.total_load)
+ cpu:push({ load / 100. })
+
+ local color = colors.blue
+ if load > 30 then
+ if load < 60 then
+ color = colors.yellow
+ elseif load < 80 then
+ color = colors.orange
+ else
+ color = colors.red
+ end
+ end
+
+ cpu:set({
+ graph = { color = color },
+ label = "cpu " .. env.total_load .. "%",
+ })
+end)
+
+cpu:subscribe("mouse.clicked", function(env)
+ sbar.exec("open -a 'Activity Monitor'")
+end)
+
+-- Background around the cpu item
+sbar.add("bracket", "widgets.cpu.bracket", { cpu.name }, {
+ -- changes color of background widget
+ background = { color = settings.cpu_background },
+})
+
+-- Background around the cpu item
+sbar.add("item", "widgets.cpu.padding", {
+ position = "right",
+ width = settings.group_paddings,
+})
diff --git a/.config/sketchybar/items/widgets/func_utils.lua b/.config/sketchybar/items/widgets/func_utils.lua
new file mode 100644
index 0000000..b60176d
--- /dev/null
+++ b/.config/sketchybar/items/widgets/func_utils.lua
@@ -0,0 +1,26 @@
+function os.capture(cmd, raw)
+ local file = assert(io.popen(cmd, "r"))
+ local output = assert(file:read("*a"))
+ file:close()
+
+ if raw then
+ return output
+ end
+
+ output = string.gsub(output, "^%s+", "")
+ output = string.gsub(output, "%s+$", "")
+ output = string.gsub(output, "[\n\r]+", "")
+
+ return output
+end
+
+-- testing battery info here... works
+Batt_info = os.capture("pmset -g batt", false)
+if Batt_info:find("AC Power") then
+ print("Found AC Power in the string.")
+else
+ local found, _, charge = Batt_info:find("(%d+)%%")
+ print("found: " .. found)
+ print("_: " .. _)
+ print("charge: " .. charge)
+end
diff --git a/.config/sketchybar/items/widgets/init.lua b/.config/sketchybar/items/widgets/init.lua
new file mode 100644
index 0000000..c919c76
--- /dev/null
+++ b/.config/sketchybar/items/widgets/init.lua
@@ -0,0 +1,4 @@
+require("items.widgets.battery")
+require("items.widgets.volume")
+require("items.widgets.wifi")
+require("items.widgets.cpu")
diff --git a/.config/sketchybar/items/widgets/volume.lua b/.config/sketchybar/items/widgets/volume.lua
new file mode 100644
index 0000000..ff6a88b
--- /dev/null
+++ b/.config/sketchybar/items/widgets/volume.lua
@@ -0,0 +1,157 @@
+local colors = require("colors")
+local icons = require("icons")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+local popup_width = 250
+
+local volume_percent = sbar.add("item", "widgets.volume1", {
+ position = "right",
+ icon = { drawing = false },
+ label = {
+ string = "??%",
+ padding_left = -1,
+ font = { family = settings.font.numbers },
+ },
+})
+
+local volume_icon = sbar.add("item", "widgets.volume2", {
+ position = "right",
+ padding_right = -1,
+ icon = {
+ string = icons.volume._100,
+ width = 0,
+ align = "left",
+ color = colors.grey,
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 14.0,
+ },
+ },
+ label = {
+ width = 25,
+ align = "left",
+ font = {
+ style = settings.font.style_map["Regular"],
+ size = 14.0,
+ },
+ },
+})
+
+local volume_bracket = sbar.add("bracket", "widgets.volume.bracket", {
+ volume_icon.name,
+ volume_percent.name,
+}, {
+ -- changes the background color of widget
+ background = { color = settings.volume_background },
+ popup = { align = "center" },
+})
+
+sbar.add("item", "widgets.volume.padding", {
+ position = "right",
+ width = settings.group_paddings,
+})
+
+local volume_slider = sbar.add("slider", popup_width, {
+ position = "popup." .. volume_bracket.name,
+ slider = {
+ highlight_color = colors.blue,
+ background = {
+ height = 6,
+ corner_radius = 3,
+ color = colors.bg2,
+ },
+ knob = {
+ string = "􀀁",
+ drawing = true,
+ },
+ },
+ background = { color = colors.bg1, height = 2, y_offset = -20 },
+ click_script = 'osascript -e "set volume output volume $PERCENTAGE"',
+})
+
+volume_percent:subscribe("volume_change", function(env)
+ local volume = tonumber(env.INFO)
+ local icon = icons.volume._0
+ if volume > 60 then
+ icon = icons.volume._100
+ elseif volume > 30 then
+ icon = icons.volume._66
+ elseif volume > 10 then
+ icon = icons.volume._33
+ elseif volume > 0 then
+ icon = icons.volume._10
+ end
+
+ local lead = ""
+ if volume < 10 then
+ lead = "0"
+ end
+
+ volume_icon:set({ label = icon })
+ volume_percent:set({ label = lead .. volume .. "%" })
+ volume_slider:set({ slider = { percentage = volume } })
+end)
+
+local function volume_collapse_details()
+ local drawing = volume_bracket:query().popup.drawing == "on"
+ if not drawing then
+ return
+ end
+ volume_bracket:set({ popup = { drawing = false } })
+ sbar.remove("/volume.device\\.*/")
+end
+
+local current_audio_device = "None"
+local function volume_toggle_details(env)
+ if env.BUTTON == "right" then
+ sbar.exec("open /System/Library/PreferencePanes/Sound.prefpane")
+ return
+ end
+
+ local should_draw = volume_bracket:query().popup.drawing == "off"
+ if should_draw then
+ volume_bracket:set({ popup = { drawing = true } })
+ sbar.exec("SwitchAudioSource -t output -c", function(result)
+ current_audio_device = result:sub(1, -2)
+ sbar.exec("SwitchAudioSource -a -t output", function(available)
+ current = current_audio_device
+ local color = colors.grey
+ local counter = 0
+
+ for device in string.gmatch(available, "[^\r\n]+") do
+ local color = colors.grey
+ if current == device then
+ color = colors.white
+ end
+ sbar.add("item", "volume.device." .. counter, {
+ position = "popup." .. volume_bracket.name,
+ width = popup_width,
+ align = "center",
+ label = { string = device, color = color },
+ click_script = 'SwitchAudioSource -s "'
+ .. device
+ .. '" && sketchybar --set /volume.device\\.*/ label.color='
+ .. colors.grey
+ .. " --set $NAME label.color="
+ .. colors.white,
+ })
+ counter = counter + 1
+ end
+ end)
+ end)
+ else
+ volume_collapse_details()
+ end
+end
+
+local function volume_scroll(env)
+ local delta = env.SCROLL_DELTA
+ sbar.exec('osascript -e "set volume output volume (output volume of (get volume settings) + ' .. delta .. ')"')
+end
+
+volume_icon:subscribe("mouse.clicked", volume_toggle_details)
+volume_icon:subscribe("mouse.scrolled", volume_scroll)
+volume_percent:subscribe("mouse.clicked", volume_toggle_details)
+volume_percent:subscribe("mouse.exited.global", volume_collapse_details)
+volume_percent:subscribe("mouse.scrolled", volume_scroll)
diff --git a/.config/sketchybar/items/widgets/wifi.lua b/.config/sketchybar/items/widgets/wifi.lua
new file mode 100644
index 0000000..c403343
--- /dev/null
+++ b/.config/sketchybar/items/widgets/wifi.lua
@@ -0,0 +1,238 @@
+local icons = require("icons")
+local colors = require("colors")
+local settings = require("settings")
+local sbar = require("sketchybar")
+
+-- Execute the event provider binary which provides the event "network_update"
+-- for the network interface "en0", which is fired every 2.0 seconds.
+sbar.exec(
+ "killall network_load >/dev/null; $CONFIG_DIR/helpers/event_providers/network_load/bin/network_load en0 network_update 2.0"
+)
+
+local popup_width = 250
+
+local wifi_up = sbar.add("item", "widgets.wifi1", {
+ position = "right",
+ padding_left = -5,
+ width = 0,
+ icon = {
+ padding_right = 0,
+ font = {
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ string = icons.wifi.upload,
+ },
+ label = {
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ color = colors.red,
+ string = "??? Bps",
+ },
+ y_offset = 4,
+})
+
+local wifi_down = sbar.add("item", "widgets.wifi2", {
+ position = "right",
+ padding_left = -5,
+ icon = {
+ padding_right = 0,
+ font = {
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ string = icons.wifi.download,
+ },
+ label = {
+ font = {
+ family = settings.font.numbers,
+ style = settings.font.style_map["Bold"],
+ size = 9.0,
+ },
+ color = colors.blue,
+ string = "??? Bps",
+ },
+ y_offset = -4,
+})
+
+local wifi = sbar.add("item", "widgets.wifi.padding", {
+ position = "right",
+ label = { drawing = false },
+})
+
+-- Background around the item
+local wifi_bracket = sbar.add("bracket", "widgets.wifi.bracket", {
+ wifi.name,
+ wifi_up.name,
+ wifi_down.name,
+}, {
+ -- changes the background color of widget
+ background = { color = settings.wifi_background },
+ popup = { align = "center", height = 30 },
+})
+
+local ssid = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ font = {
+ style = settings.font.style_map["Bold"],
+ },
+ string = icons.wifi.router,
+ },
+ width = popup_width,
+ align = "center",
+ label = {
+ font = {
+ size = 15,
+ style = settings.font.style_map["Bold"],
+ },
+ max_chars = 18,
+ string = "????????????",
+ },
+ background = {
+ height = 2,
+ color = colors.grey,
+ y_offset = -15,
+ },
+})
+
+local hostname = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Hostname:",
+ width = popup_width / 2,
+ },
+ label = {
+ max_chars = 20,
+ string = "????????????",
+ width = popup_width / 2,
+ align = "right",
+ },
+})
+
+local ip = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "IP:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ },
+})
+
+local mask = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Subnet mask:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ },
+})
+
+local router = sbar.add("item", {
+ position = "popup." .. wifi_bracket.name,
+ icon = {
+ align = "left",
+ string = "Router:",
+ width = popup_width / 2,
+ },
+ label = {
+ string = "???.???.???.???",
+ width = popup_width / 2,
+ align = "right",
+ },
+})
+
+sbar.add("item", { position = "right", width = settings.group_paddings })
+
+wifi_up:subscribe("network_update", function(env)
+ local up_color = (env.upload == "000 Bps") and colors.grey or colors.red
+ local down_color = (env.download == "000 Bps") and colors.grey or colors.blue
+ wifi_up:set({
+ icon = { color = up_color },
+ label = {
+ string = env.upload,
+ color = up_color,
+ },
+ })
+ wifi_down:set({
+ icon = { color = down_color },
+ label = {
+ string = env.download,
+ color = down_color,
+ },
+ })
+end)
+
+wifi:subscribe({ "wifi_change", "system_woke" }, function(env)
+ sbar.exec("ipconfig getifaddr en0", function(ip)
+ local connected = not (ip == "")
+ wifi:set({
+ icon = {
+ string = connected and icons.wifi.connected or icons.wifi.disconnected,
+ color = connected and colors.white or colors.red,
+ },
+ })
+ end)
+end)
+
+local function hide_details()
+ wifi_bracket:set({ popup = { drawing = false } })
+end
+
+local function toggle_details()
+ local should_draw = wifi_bracket:query().popup.drawing == "off"
+ if should_draw then
+ wifi_bracket:set({ popup = { drawing = true } })
+ sbar.exec("networksetup -getcomputername", function(result)
+ hostname:set({ label = result })
+ end)
+ sbar.exec("ipconfig getifaddr en0", function(result)
+ ip:set({ label = result })
+ end)
+ sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(result)
+ ssid:set({ label = result })
+ end)
+ sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Subnet mask: ' '/^Subnet mask: / {print $2}'", function(result)
+ mask:set({ label = result })
+ end)
+ sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Router: ' '/^Router: / {print $2}'", function(result)
+ router:set({ label = result })
+ end)
+ else
+ hide_details()
+ end
+end
+
+wifi_up:subscribe("mouse.clicked", toggle_details)
+wifi_down:subscribe("mouse.clicked", toggle_details)
+wifi:subscribe("mouse.clicked", toggle_details)
+wifi:subscribe("mouse.exited.global", hide_details)
+
+local function copy_label_to_clipboard(env)
+ local label = sbar.query(env.NAME).label.value
+ sbar.exec('echo "' .. label .. '" | pbcopy')
+ sbar.set(env.NAME, { label = { string = icons.clipboard, align = "center" } })
+ sbar.delay(1, function()
+ sbar.set(env.NAME, { label = { string = label, align = "right" } })
+ end)
+end
+
+ssid:subscribe("mouse.clicked", copy_label_to_clipboard)
+hostname:subscribe("mouse.clicked", copy_label_to_clipboard)
+ip:subscribe("mouse.clicked", copy_label_to_clipboard)
+mask:subscribe("mouse.clicked", copy_label_to_clipboard)
+router:subscribe("mouse.clicked", copy_label_to_clipboard)
diff --git a/.config/sketchybar/settings.lua b/.config/sketchybar/settings.lua
new file mode 100644
index 0000000..bad1d71
--- /dev/null
+++ b/.config/sketchybar/settings.lua
@@ -0,0 +1,50 @@
+local colors = require("colors")
+return {
+ -- widgets borders; cpu, wifi, vol, batt
+ widget_borders = colors.grey,
+ -- battery widget
+ batt_background = colors.black,
+ batt_color_default = colors.green,
+ batt_color_25 = colors.cog_blue,
+ batt_color_0 = colors.orange,
+ -- cpu widget
+ cpu_background = colors.black,
+ -- volume widget
+ volume_background = colors.black,
+ -- wifi widget
+ wifi_background = colors.black,
+ -- apple.lua
+ apple_icon = colors.white,
+ apple_background = colors.black,
+ apple_border = colors.black,
+ -- calendar.lua
+ calendar_background = colors.black,
+ calendar_border = colors.black,
+ -- spaces.lua
+ spaces_highlight = colors.pink,
+ spaces_icon = colors.grey,
+ spaces_background = colors.black,
+ spaces_border = colors.grey,
+ spaces_selected = colors.white,
+
+ paddings = 3,
+ group_paddings = 5,
+
+ icons = "sf-symbols", -- alternatively available: NerdFont
+
+ -- This is a font configuration for SF Pro and SF Mono (installed manually)
+ font = require("helpers.default_font"),
+
+ -- Alternatively, this is a font config for JetBrainsMono Nerd Font
+ -- font = {
+ -- text = "JetBrainsMono Nerd Font", -- Used for text
+ -- numbers = "JetBrainsMono Nerd Font", -- Used for numbers
+ -- style_map = {
+ -- ["Regular"] = "Regular",
+ -- ["Semibold"] = "Medium",
+ -- ["Bold"] = "SemiBold",
+ -- ["Heavy"] = "Bold",
+ -- ["Black"] = "ExtraBold",
+ -- },
+ -- },
+}
diff --git a/.config/sketchybar/sketchybarrc b/.config/sketchybar/sketchybarrc
new file mode 100755
index 0000000..95ece11
--- /dev/null
+++ b/.config/sketchybar/sketchybarrc
@@ -0,0 +1,5 @@
+#!/usr/bin/env lua
+
+-- Load the sketchybar-package and prepare the helper binaries
+require("helpers")
+require("init")