feat: new config for sketchybar
This commit is contained in:
parent
cc55237709
commit
4c8ccec1ae
47 changed files with 1792 additions and 154 deletions
21
bin/presentation-mode
Executable file
21
bin/presentation-mode
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This script is used to change the top and bottom padding of the outer container in the Aerospace theme.
|
||||
|
||||
presentation_pixel_gaps=300
|
||||
top_normal_pixel_gaps=82
|
||||
bottom_normal_pixel_gaps=40
|
||||
terminal_font_size=18
|
||||
terminal_presentation_font_size=22
|
||||
|
||||
if [ $1 == "on" ]; then
|
||||
sed -i '' "s/\(outer\.top = *\[.*\), $top_normal_pixel_gaps]/\1, $presentation_pixel_gaps]/" ~/.config/aerospace/aerospace.toml
|
||||
sed -i '' "s/\(outer\.bottom = *\[.*\), $bottom_normal_pixel_gaps]/\1, $presentation_pixel_gaps]/" ~/.config/aerospace/aerospace.toml
|
||||
osascript -e 'tell application "System Events" to set picture of every desktop to "/Users/stefan.pinter/Pictures/Wallpapers/black-gray.jpg"'
|
||||
aerospace reload-config
|
||||
elif [ $1 == "off" ]; then
|
||||
sed -i '' "s/\(outer\.top = *\[.*\), $presentation_pixel_gaps]/\1, $top_normal_pixel_gaps]/" ~/.config/aerospace/aerospace.toml
|
||||
sed -i '' "s/\(outer\.bottom = *\[.*\), $presentation_pixel_gaps]/\1, $bottom_normal_pixel_gaps]/" ~/.config/aerospace/aerospace.toml
|
||||
osascript -e 'tell application "System Events" to set picture of every desktop to "/Users/rayandrew/Pictures/Wallpapers/bluering.png"'
|
||||
aerospace reload-config
|
||||
fi
|
||||
|
|
@ -2,7 +2,6 @@ config-version = 2
|
|||
|
||||
after-startup-command = [
|
||||
"workspace 10",
|
||||
"layout h_accordion",
|
||||
"workspace-back-and-forth"
|
||||
]
|
||||
|
||||
|
|
@ -11,15 +10,20 @@ enable-normalization-flatten-containers = false
|
|||
enable-normalization-opposite-orientation-for-nested-containers = false
|
||||
on-focused-monitor-changed = ['move-mouse monitor-lazy-center']
|
||||
exec-on-workspace-change = ['/bin/bash', '-c',
|
||||
'/run/current-system/sw/bin/sketchybar --trigger aerospace_workspace_change FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE PREV_WORKSPACE=$AEROSPACE_PREV_WORKSPACE && /etc/profiles/per-user/rayandrew/bin/aerospace-scratchpad hook pull-window $AEROSPACE_PREV_WORKSPACE $AEROSPACE_FOCUSED_WORKSPACE'
|
||||
'/run/current-system/sw/bin/sketchybar --trigger aerospace_workspace_changed FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE PREV_WORKSPACE=$AEROSPACE_PREV_WORKSPACE && /etc/profiles/per-user/rayandrew/bin/aerospace-scratchpad hook pull-window $AEROSPACE_PREV_WORKSPACE $AEROSPACE_FOCUSED_WORKSPACE'
|
||||
]
|
||||
on-focus-changed = [
|
||||
'move-mouse window-lazy-center',
|
||||
'exec-and-forget /bin/bash -c /run/current-system/sw/bin/sketchybar --trigger front_app_switched',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger update_windows'
|
||||
]
|
||||
|
||||
[gaps]
|
||||
inner.horizontal = [{ monitor.'^built-in retina display$' = 10 }, 15]
|
||||
inner.vertical = [{ monitor.'^built-in retina display$' = 10 }, 15]
|
||||
outer.left = [{ monitor.'^built-in retina display$' = 5 }, 15]
|
||||
outer.right = [{ monitor.'^built-in retina display$' = 5 }, 15]
|
||||
outer.bottom = [{ monitor.'^built-in retina display$' = 5 }, 15]
|
||||
inner.horizontal = [{ monitor.'^built-in retina display$' = 15 }, 15]
|
||||
inner.vertical = [{ monitor.'^built-in retina display$' = 15 }, 15]
|
||||
outer.left = [{ monitor.'^built-in retina display$' = 15 }, 15]
|
||||
outer.right = [{ monitor.'^built-in retina display$' = 15 }, 15]
|
||||
outer.bottom = [{ monitor.'^built-in retina display$' = 15 }, 15]
|
||||
outer.top = [{ monitor.'^built-in retina display$' = 15 }, 50]
|
||||
|
||||
[mode.main.binding]
|
||||
|
|
@ -41,6 +45,7 @@ exec-on-workspace-change = ['/bin/bash', '-c',
|
|||
alt-f = 'fullscreen'
|
||||
|
||||
alt-s = 'layout v_accordion'
|
||||
alt-t = 'layout h_accordion'
|
||||
alt-e = 'layout tiles horizontal vertical'
|
||||
alt-space = 'layout floating tiling'
|
||||
|
||||
|
|
@ -66,9 +71,14 @@ exec-on-workspace-change = ['/bin/bash', '-c',
|
|||
alt-shift-9 = 'move-node-to-workspace 9'
|
||||
alt-shift-0 = 'move-node-to-workspace 10'
|
||||
|
||||
alt-shift-semicolon = 'mode service'
|
||||
alt-r = 'mode resize'
|
||||
|
||||
alt-shift-semicolon = [
|
||||
'mode service',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger send_message MESSAGE="SERVICE MODE" HOLD="true"'
|
||||
]
|
||||
alt-r = [
|
||||
'mode resize',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger send_message MESSAGE="RESIZE MODE" HOLD="true"'
|
||||
]
|
||||
|
||||
cmd-ctrl-1 = "exec-and-forget aerospace-scratchpad show Finder"
|
||||
|
||||
|
|
@ -77,11 +87,22 @@ exec-on-workspace-change = ['/bin/bash', '-c',
|
|||
j = 'resize height +50'
|
||||
k = 'resize height -50'
|
||||
l = 'resize width +50'
|
||||
enter = 'mode main'
|
||||
esc = 'mode main'
|
||||
esc = [
|
||||
'mode main',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger hide_message'
|
||||
]
|
||||
enter = [
|
||||
'mode main',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger hide_message'
|
||||
]
|
||||
|
||||
[mode.service.binding]
|
||||
c = ['reload-config', 'mode main']
|
||||
esc = [
|
||||
'reload-config',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger hide_message',
|
||||
'exec-and-forget /run/current-system/sw/bin/sketchybar --reload',
|
||||
'mode main',
|
||||
]
|
||||
r = ['flatten-workspace-tree', 'mode main']
|
||||
f = ['layout floating tiling', 'mode main']
|
||||
backspace = ['close-all-windows-but-current', 'mode main']
|
||||
|
|
@ -102,3 +123,19 @@ exec-on-workspace-change = ['/bin/bash', '-c',
|
|||
[[on-window-detected]]
|
||||
if.app-id = 'com.1password.1password'
|
||||
run = ['layout floating']
|
||||
|
||||
[[on-window-detected]]
|
||||
if.app-id = 'com.spotify.client'
|
||||
run = ['move-node-to-workspace 7']
|
||||
|
||||
[[on-window-detected]]
|
||||
if.app-id = 'com.apple.mail'
|
||||
run = ['move-node-to-workspace 8']
|
||||
|
||||
[[on-window-detected]]
|
||||
if.app-id = 'com.microsoft.teams2'
|
||||
run = ['move-node-to-workspace 9']
|
||||
|
||||
[[on-window-detected]]
|
||||
if.app-id = 'com.tinyspeck.slackmacgap'
|
||||
run = ['move-node-to-workspace 9']
|
||||
|
|
|
|||
23
config/old_sketchybar/bar.lua
Normal file
23
config/old_sketchybar/bar.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require 'colors'
|
||||
|
||||
local bar_height = 35
|
||||
|
||||
sbar.bar {
|
||||
blur_radius = 20,
|
||||
border_color = colors.bar.border,
|
||||
border_width = 2,
|
||||
color = colors.bar.bg,
|
||||
corner_radius = 5,
|
||||
height = bar_height,
|
||||
margin = 10,
|
||||
notch_width = 0,
|
||||
padding_left = 10,
|
||||
padding_right = 10,
|
||||
position = 'top',
|
||||
shadow = true,
|
||||
sticky = true,
|
||||
topmost = false,
|
||||
y_offset = 2,
|
||||
}
|
||||
56
config/old_sketchybar/init.lua
Normal file
56
config/old_sketchybar/init.lua
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
sbar.default {
|
||||
updates = 'when_shown',
|
||||
icon = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Bold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
background = { image = { corner_radius = 9 } },
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Semibold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
},
|
||||
background = {
|
||||
height = 30,
|
||||
corner_radius = 12,
|
||||
border_width = 1,
|
||||
-- border_color = colors.bar.border,
|
||||
image = {
|
||||
corner_radius = 8,
|
||||
-- border_color = colors.grey,
|
||||
border_width = 1,
|
||||
},
|
||||
},
|
||||
popup = {
|
||||
background = {
|
||||
border_width = 1,
|
||||
corner_radius = 8,
|
||||
border_color = colors.popup.border,
|
||||
color = colors.popup.bg,
|
||||
shadow = { drawing = true },
|
||||
},
|
||||
blur_radius = 20,
|
||||
},
|
||||
padding_left = 5,
|
||||
padding_right = 5,
|
||||
scroll_texts = true,
|
||||
}
|
||||
|
||||
require 'bar'
|
||||
require 'items'
|
||||
37
config/old_sketchybar/items/apple.lua
Normal file
37
config/old_sketchybar/items/apple.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
local colors = require 'colors'
|
||||
local icons = require 'icons'
|
||||
local settings = require 'settings'
|
||||
|
||||
-- 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 = settings.paddings,
|
||||
padding_left = 0,
|
||||
color = colors.fg,
|
||||
},
|
||||
label = { drawing = false },
|
||||
background = {
|
||||
color = colors.bar.bg,
|
||||
-- border_color = colors.black,
|
||||
-- border_width = 1
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = 'sk-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 })
|
||||
34
config/old_sketchybar/items/init.lua
Normal file
34
config/old_sketchybar/items/init.lua
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
local function file_exists(path)
|
||||
local f = io.open(path, 'r')
|
||||
if f then
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function load_module_if_program_exists(module_name, binary_path)
|
||||
if file_exists(binary_path) then
|
||||
print('Loading ' .. module_name .. ' (found at ' .. binary_path .. ')')
|
||||
local ok, err = pcall(require, module_name)
|
||||
if not ok then
|
||||
print('ERROR loading ' .. module_name .. ' module: ' .. tostring(err))
|
||||
else
|
||||
print('Successfully loaded ' .. module_name)
|
||||
end
|
||||
else
|
||||
print('Skipping ' .. module_name .. ' (binary not found at ' .. binary_path .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
require 'items.apple'
|
||||
-- require 'items.aerospace'
|
||||
load_module_if_program_exists('items.aerospace', '/opt/homebrew/bin/aerospace')
|
||||
load_module_if_program_exists('items.yabai', '/etc/profiles/per-user/rayandrew/bin/yabai')
|
||||
require 'items.front_app'
|
||||
require 'items.menu'
|
||||
require 'items.battery'
|
||||
require 'items.cal'
|
||||
require 'items.volume'
|
||||
require 'items.cpu'
|
||||
require 'items.wifi'
|
||||
1
config/sketchybar/README.md
Normal file
1
config/sketchybar/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Shamelessly copied from https://github.com/agenttank/dotfiles_macos/tree/1feca82518312cd8c4a784032471fedfa895989d
|
||||
|
|
@ -1,23 +1,15 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require 'colors'
|
||||
|
||||
local bar_height = 35
|
||||
local settings = require 'config.settings'
|
||||
|
||||
sbar.bar {
|
||||
blur_radius = 20,
|
||||
border_color = colors.bar.border,
|
||||
border_width = 2,
|
||||
color = colors.bar.bg,
|
||||
corner_radius = 5,
|
||||
height = bar_height,
|
||||
margin = 10,
|
||||
notch_width = 0,
|
||||
padding_left = 10,
|
||||
padding_right = 10,
|
||||
position = 'top',
|
||||
shadow = true,
|
||||
sticky = true,
|
||||
topmost = false,
|
||||
y_offset = 2,
|
||||
topmost = 'window',
|
||||
height = settings.dimens.graphics.bar.height,
|
||||
color = settings.colors.bar.transparent,
|
||||
padding_right = settings.dimens.padding.right,
|
||||
padding = settings.dimens.padding.bar,
|
||||
padding_left = settings.dimens.padding.left,
|
||||
margin = settings.dimens.padding.bar,
|
||||
corner_radius = settings.dimens.graphics.background.corner_radius,
|
||||
y_offset = settings.dimens.graphics.bar.offset,
|
||||
-- blur_radius = settings.dimens.graphics.blur_radius,
|
||||
border_width = 0,
|
||||
}
|
||||
|
|
|
|||
38
config/sketchybar/config/colors.lua
Normal file
38
config/sketchybar/config/colors.lua
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
local colors <const> = {
|
||||
black = 0xff181819,
|
||||
white = 0xfff8f8f2,
|
||||
red = 0xf1FD6592,
|
||||
green = 0xff007692,
|
||||
blue = 0xff5199ba,
|
||||
yellow = 0xffffff81,
|
||||
orange = 0xfff4c07b,
|
||||
magenta = 0xd3fc7ebd,
|
||||
purple = 0xff796fa9,
|
||||
other_purple = 0xff302c45,
|
||||
cyan = 0xff7bf2de,
|
||||
grey = 0xff7f8490,
|
||||
dirty_white = 0xc8cad3f5,
|
||||
dark_grey = 0xff2b2736,
|
||||
transparent = 0x00000000,
|
||||
bar = {
|
||||
bg = 0xf1151320,
|
||||
border = 0xff2c2e34,
|
||||
},
|
||||
popup = {
|
||||
bg = 0xf1151320,
|
||||
border = 0xff2c2e34,
|
||||
},
|
||||
slider = {
|
||||
bg = 0xf1151320,
|
||||
border = 0xff2c2e34,
|
||||
},
|
||||
bg1 = 0xd322212c,
|
||||
bg2 = 0xff302c45,
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
return colors
|
||||
40
config/sketchybar/config/dimens.lua
Normal file
40
config/sketchybar/config/dimens.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
local padding <const> = {
|
||||
background = 8,
|
||||
icon = 10,
|
||||
label = 8,
|
||||
bar = 10,
|
||||
left = 12,
|
||||
right = 12,
|
||||
item = 18,
|
||||
popup = 8,
|
||||
}
|
||||
|
||||
local graphics <const> = {
|
||||
bar = {
|
||||
height = 30,
|
||||
offset = 8,
|
||||
},
|
||||
background = {
|
||||
height = 24,
|
||||
corner_radius = 9,
|
||||
},
|
||||
slider = {
|
||||
height = 20,
|
||||
},
|
||||
popup = {
|
||||
width = 200,
|
||||
large_width = 300,
|
||||
},
|
||||
blur_radius = 30,
|
||||
}
|
||||
|
||||
local text <const> = {
|
||||
icon = 16.0,
|
||||
label = 14.0,
|
||||
}
|
||||
|
||||
return {
|
||||
padding = padding,
|
||||
graphics = graphics,
|
||||
text = text,
|
||||
}
|
||||
14
config/sketchybar/config/fonts.lua
Normal file
14
config/sketchybar/config/fonts.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
local dimens <const> = require 'config.dimens'
|
||||
|
||||
return {
|
||||
text = 'SpaceMono Nerd Font',
|
||||
numbers = 'SpaceMono Nerd Font',
|
||||
icons = function(size)
|
||||
local font = 'sketchybar-app-font:Regular'
|
||||
return size and font .. ':' .. size or font .. ':' .. dimens.text.icon
|
||||
end,
|
||||
styles = {
|
||||
regular = 'Regular',
|
||||
bold = 'Bold',
|
||||
},
|
||||
}
|
||||
331
config/sketchybar/config/icons.lua
Normal file
331
config/sketchybar/config/icons.lua
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
local apps <const> = {
|
||||
['Live'] = ':ableton:',
|
||||
['Adobe Bridge 2024'] = ':adobe_bridge:',
|
||||
['Affinity Designer'] = ':affinity_designer:',
|
||||
['Affinity Designer 2'] = ':affinity_designer_2:',
|
||||
['Affinity Photo'] = ':affinity_photo:',
|
||||
['Affinity Photo 2'] = ':affinity_photo_2:',
|
||||
['Affinity Publisher'] = ':affinity_publisher:',
|
||||
['Affinity Publisher 2'] = ':affinity_publisher_2:',
|
||||
['Airmail'] = ':airmail:',
|
||||
['Alacritty'] = ':alacritty:',
|
||||
['Alfred Preferences'] = ':alfred:',
|
||||
['Android Messages'] = ':android_messages:',
|
||||
['Android Studio'] = ':android_studio:',
|
||||
['Anytype'] = ':anytype:',
|
||||
['App Eraser'] = ':app_eraser:',
|
||||
['App Store'] = ':app_store:',
|
||||
['Arc'] = ':arc:',
|
||||
['Atom'] = ':atom:',
|
||||
['Audacity'] = ':audacity:',
|
||||
['Bambu Studio'] = ':bambu_studio:',
|
||||
['MoneyMoney'] = ':bank:',
|
||||
['Bear'] = ':bear:',
|
||||
['BetterTouchTool'] = ':bettertouchtool:',
|
||||
['Bilibili'] = ':bilibili:',
|
||||
['哔哩哔哩'] = ':bilibili:',
|
||||
['Bitwarden'] = ':bit_warden:',
|
||||
['Blender'] = ':blender:',
|
||||
['BluOS Controller'] = ':bluos_controller:',
|
||||
['Calibre'] = ':book:',
|
||||
['Brave Browser'] = ':brave_browser:',
|
||||
['Calculator'] = ':calculator:',
|
||||
['Soulver 3'] = ':calculator:',
|
||||
['Calculette'] = ':calculator:',
|
||||
['Calendar'] = ':calendar:',
|
||||
['日历'] = ':calendar:',
|
||||
['Fantastical'] = ':calendar:',
|
||||
['Cron'] = ':calendar:',
|
||||
['Amie'] = ':calendar:',
|
||||
['Calendrier'] = ':calendar:',
|
||||
['Notion Calendar'] = ':calendar:',
|
||||
['Caprine'] = ':caprine:',
|
||||
['Citrix Workspace'] = ':citrix:',
|
||||
['Citrix Viewer'] = ':citrix:',
|
||||
['ClickUp'] = ':click_up:',
|
||||
['Code'] = ':code:',
|
||||
['Code - Insiders'] = ':code:',
|
||||
['Color Picker'] = ':color_picker:',
|
||||
['数码测色计'] = ':color_picker:',
|
||||
['CotEditor'] = ':coteditor:',
|
||||
['Cypress'] = ':cypress:',
|
||||
['DataGrip'] = ':datagrip:',
|
||||
['DataSpell'] = ':dataspell:',
|
||||
['DaVinci Resolve'] = ':davinciresolve:',
|
||||
['Default'] = ':default:',
|
||||
['CleanMyMac X'] = ':desktop:',
|
||||
['DEVONthink 3'] = ':devonthink3:',
|
||||
['DingTalk'] = ':dingtalk:',
|
||||
['钉钉'] = ':dingtalk:',
|
||||
['阿里钉'] = ':dingtalk:',
|
||||
['Discord'] = ':discord:',
|
||||
['Discord Canary'] = ':discord:',
|
||||
['Discord PTB'] = ':discord:',
|
||||
['Docker'] = ':docker:',
|
||||
['Docker Desktop'] = ':docker:',
|
||||
['GrandTotal'] = ':dollar:',
|
||||
['Receipts'] = ':dollar:',
|
||||
['Double Commander'] = ':doublecmd:',
|
||||
['Drafts'] = ':drafts:',
|
||||
['Dropbox'] = ':dropbox:',
|
||||
['Element'] = ':element:',
|
||||
['Emacs'] = ':emacs:',
|
||||
['Evernote Legacy'] = ':evernote_legacy:',
|
||||
['FaceTime'] = ':face_time:',
|
||||
['FaceTime 通话'] = ':face_time:',
|
||||
['Figma'] = ':figma:',
|
||||
['Final Cut Pro'] = ':final_cut_pro:',
|
||||
['Finder'] = ':finder:',
|
||||
['访达'] = ':finder:',
|
||||
['Firefox'] = ':firefox:',
|
||||
['Firefox Developer Edition'] = ':firefox_developer_edition:',
|
||||
['Firefox Nightly'] = ':firefox_developer_edition:',
|
||||
['Folx'] = ':folx:',
|
||||
['Fusion'] = ':fusion:',
|
||||
['System Preferences'] = ':gear:',
|
||||
['System Settings'] = ':gear:',
|
||||
['Systemeinstellungen'] = ':gear:',
|
||||
['系统设置'] = ':gear:',
|
||||
['Réglages Système'] = ':gear:',
|
||||
['GitHub Desktop'] = ':git_hub:',
|
||||
['Godot'] = ':godot:',
|
||||
['GoLand'] = ':goland:',
|
||||
['Chromium'] = ':google_chrome:',
|
||||
['Google Chrome'] = ':google_chrome:',
|
||||
['Google Chrome Canary'] = ':google_chrome:',
|
||||
['Grammarly Editor'] = ':grammarly:',
|
||||
['Home Assistant'] = ':home_assistant:',
|
||||
['Hyper'] = ':hyper:',
|
||||
['IntelliJ IDEA'] = ':idea:',
|
||||
['Inkdrop'] = ':inkdrop:',
|
||||
['Inkscape'] = ':inkscape:',
|
||||
['Insomnia'] = ':insomnia:',
|
||||
['Iris'] = ':iris:',
|
||||
['iTerm'] = ':iterm:',
|
||||
['iTerm2'] = ':iterm:',
|
||||
['Jellyfin Media Player'] = ':jellyfin:',
|
||||
['Joplin'] = ':joplin:',
|
||||
['카카오톡'] = ':kakaotalk:',
|
||||
['KakaoTalk'] = ':kakaotalk:',
|
||||
['Kakoune'] = ':kakoune:',
|
||||
['KeePassXC'] = ':kee_pass_x_c:',
|
||||
['Secrets'] = ':one_password:',
|
||||
['Keyboard Maestro'] = ':keyboard_maestro:',
|
||||
['Keynote'] = ':keynote:',
|
||||
['Keynote 讲演'] = ':keynote:',
|
||||
['kitty'] = ':kitty:',
|
||||
['League of Legends'] = ':league_of_legends:',
|
||||
['LibreWolf'] = ':libre_wolf:',
|
||||
['Adobe Lightroom'] = ':lightroom:',
|
||||
['Lightroom Classic'] = ':lightroomclassic:',
|
||||
['LINE'] = ':line:',
|
||||
['Linear'] = ':linear:',
|
||||
['LM Studio'] = ':lm_studio:',
|
||||
['LocalSend'] = ':localsend:',
|
||||
['Logic Pro'] = ':logicpro:',
|
||||
['Logseq'] = ':logseq:',
|
||||
['Canary Mail'] = ':mail:',
|
||||
['HEY'] = ':mail:',
|
||||
['Mail'] = ':mail:',
|
||||
['Mailspring'] = ':mail:',
|
||||
['MailMate'] = ':mail:',
|
||||
['Superhuman'] = ':mail:',
|
||||
['邮件'] = ':mail:',
|
||||
['MAMP'] = ':mamp:',
|
||||
['MAMP PRO'] = ':mamp:',
|
||||
['Maps'] = ':maps:',
|
||||
['Google Maps'] = ':maps:',
|
||||
['Matlab'] = ':matlab:',
|
||||
['Mattermost'] = ':mattermost:',
|
||||
['Messages'] = ':messages:',
|
||||
['信息'] = ':messages:',
|
||||
['Nachrichten'] = ':messages:',
|
||||
['Messenger'] = ':messenger:',
|
||||
['Microsoft Edge'] = ':microsoft_edge:',
|
||||
['Microsoft Excel'] = ':microsoft_excel:',
|
||||
['Microsoft Outlook'] = ':microsoft_outlook:',
|
||||
['Microsoft PowerPoint'] = ':microsoft_power_point:',
|
||||
['Microsoft Remote Desktop'] = ':microsoft_remote_desktop:',
|
||||
['Microsoft Teams'] = ':microsoft_teams:',
|
||||
['Microsoft Teams (work or school)'] = ':microsoft_teams:',
|
||||
['Microsoft Word'] = ':microsoft_word:',
|
||||
['Min'] = ':min_browser:',
|
||||
['Miro'] = ':miro:',
|
||||
['MongoDB Compass'] = ':mongodb:',
|
||||
['mpv'] = ':mpv:',
|
||||
['Mullvad Browser'] = ':mullvad_browser:',
|
||||
['Music'] = ':music:',
|
||||
['音乐'] = ':music:',
|
||||
['Musique'] = ':music:',
|
||||
['Neovide'] = ':neovide:',
|
||||
['neovide'] = ':neovide:',
|
||||
['Neovim'] = ':neovim:',
|
||||
['neovim'] = ':neovim:',
|
||||
['nvim'] = ':neovim:',
|
||||
['网易云音乐'] = ':netease_music:',
|
||||
['Noodl'] = ':noodl:',
|
||||
['Noodl Editor'] = ':noodl:',
|
||||
['NordVPN'] = ':nord_vpn:',
|
||||
['Notability'] = ':notability:',
|
||||
['Notes'] = ':notes:',
|
||||
['Notizen'] = ':notes:',
|
||||
['备忘录'] = ':notes:',
|
||||
['Notion'] = ':notion:',
|
||||
['Nova'] = ':nova:',
|
||||
['Numbers'] = ':numbers:',
|
||||
['Numbers 表格'] = ':numbers:',
|
||||
['Obsidian'] = ':obsidian:',
|
||||
['OBS'] = ':obsstudio:',
|
||||
['OmniFocus'] = ':omni_focus:',
|
||||
['1Password'] = ':one_password:',
|
||||
['ChatGPT'] = ':openai:',
|
||||
['OpenVPN Connect'] = ':openvpn_connect:',
|
||||
['Opera'] = ':opera:',
|
||||
['OrcaSlicer'] = ':orcaslicer:',
|
||||
['Orion'] = ':orion:',
|
||||
['Orion RC'] = ':orion:',
|
||||
['Pages'] = ':pages:',
|
||||
['Pages 文稿'] = ':pages:',
|
||||
['Parallels Desktop'] = ':parallels:',
|
||||
['Parsec'] = ':parsec:',
|
||||
['Preview'] = ':pdf:',
|
||||
['预览'] = ':pdf:',
|
||||
['Skim'] = ':pdf:',
|
||||
['zathura'] = ':pdf:',
|
||||
['Aperçu'] = ':pdf:',
|
||||
['PDF Expert'] = ':pdf_expert:',
|
||||
['Adobe Photoshop'] = ':photoshop:',
|
||||
['Pi-hole Remote'] = ':pihole:',
|
||||
['Pine'] = ':pine:',
|
||||
['Podcasts'] = ':podcasts:',
|
||||
['播客'] = ':podcasts:',
|
||||
['PomoDone App'] = ':pomodone:',
|
||||
['Postman'] = ':postman:',
|
||||
['PrusaSlicer'] = ':prusaslicer:',
|
||||
['SuperSlicer'] = ':prusaslicer:',
|
||||
['PyCharm'] = ':pycharm:',
|
||||
['QQ'] = ':qq:',
|
||||
['QQ音乐'] = ':qqmusic:',
|
||||
['QQMusic'] = ':qqmusic:',
|
||||
['Quantumult X'] = ':quantumult_x:',
|
||||
['qutebrowser'] = ':qute_browser:',
|
||||
['Raindrop.io'] = ':raindrop_io:',
|
||||
['Reeder'] = ':reeder5:',
|
||||
['Reminders'] = ':reminders:',
|
||||
['提醒事项'] = ':reminders:',
|
||||
['Rappels'] = ':reminders:',
|
||||
['Replit'] = ':replit:',
|
||||
['Rider'] = ':rider:',
|
||||
['JetBrains Rider'] = ':rider:',
|
||||
['Safari'] = ':safari:',
|
||||
['Safari浏览器'] = ':safari:',
|
||||
['Safari Technology Preview'] = ':safari:',
|
||||
['Sequel Ace'] = ':sequel_ace:',
|
||||
['Sequel Pro'] = ':sequel_pro:',
|
||||
['Setapp'] = ':setapp:',
|
||||
['SF Symbols'] = ':sf_symbols:',
|
||||
['Signal'] = ':signal:',
|
||||
['Sketch'] = ':sketch:',
|
||||
['Skype'] = ':skype:',
|
||||
['Slack'] = ':slack:',
|
||||
['Spark'] = ':spark:',
|
||||
['Spotify'] = ':spotify:',
|
||||
['Spotlight'] = ':spotlight:',
|
||||
['Sublime Text'] = ':sublime_text:',
|
||||
['Tana'] = ':tana:',
|
||||
['TeamSpeak 3'] = ':team_speak:',
|
||||
['Telegram'] = ':telegram:',
|
||||
['Terminal'] = ':terminal:',
|
||||
['终端'] = ':terminal:',
|
||||
['Typora'] = ':text:',
|
||||
['Microsoft To Do'] = ':things:',
|
||||
['Things'] = ':things:',
|
||||
['Thunderbird'] = ':thunderbird:',
|
||||
['TickTick'] = ':tick_tick:',
|
||||
['TIDAL'] = ':tidal:',
|
||||
['Tiny RDM'] = ':tinyrdm:',
|
||||
['Todoist'] = ':todoist:',
|
||||
['Toggl Track'] = ':toggl_track:',
|
||||
['Tor Browser'] = ':tor_browser:',
|
||||
['Tower'] = ':tower:',
|
||||
['Transmit'] = ':transmit:',
|
||||
['Trello'] = ':trello:',
|
||||
['Tweetbot'] = ':twitter:',
|
||||
['Twitter'] = ':twitter:',
|
||||
['MacVim'] = ':vim:',
|
||||
['Vim'] = ':vim:',
|
||||
['VimR'] = ':vim:',
|
||||
['Vivaldi'] = ':vivaldi:',
|
||||
['VLC'] = ':vlc:',
|
||||
['VMware Fusion'] = ':vmware_fusion:',
|
||||
['VSCodium'] = ':vscodium:',
|
||||
['Warp'] = ':warp:',
|
||||
['WebStorm'] = ':web_storm:',
|
||||
['微信'] = ':wechat:',
|
||||
['WeChat'] = ':wechat:',
|
||||
['企业微信'] = ':wecom:',
|
||||
['WeCom'] = ':wecom:',
|
||||
['WezTerm'] = ':wezterm:',
|
||||
['WhatsApp'] = ':whats_app:',
|
||||
['WhatsApp'] = ':whats_app:',
|
||||
['Xcode'] = ':xcode:',
|
||||
['Яндекс Музыка'] = ':yandex_music:',
|
||||
['Yuque'] = ':yuque:',
|
||||
['语雀'] = ':yuque:',
|
||||
['Zed'] = ':zed:',
|
||||
['Zeplin'] = ':zeplin:',
|
||||
['zoom.us'] = ':zoom:',
|
||||
['Zotero'] = ':zotero:',
|
||||
['Zulip'] = ':zulip:',
|
||||
['default'] = ':default:',
|
||||
}
|
||||
|
||||
local text <const> = {
|
||||
nerdfont = {
|
||||
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 = '',
|
||||
},
|
||||
slider = {
|
||||
knob = '',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
text = text.nerdfont,
|
||||
apps = apps,
|
||||
}
|
||||
1
config/sketchybar/config/init.lua
Normal file
1
config/sketchybar/config/init.lua
Normal file
|
|
@ -0,0 +1 @@
|
|||
return require 'config.settings'
|
||||
11
config/sketchybar/config/settings.lua
Normal file
11
config/sketchybar/config/settings.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
local colors <const> = require 'config.colors'
|
||||
local fonts <const> = require 'config.fonts'
|
||||
local icons <const> = require 'config.icons'
|
||||
local dimens <const> = require 'config.dimens'
|
||||
|
||||
return {
|
||||
fonts = fonts,
|
||||
dimens = dimens,
|
||||
colors = colors,
|
||||
icons = icons,
|
||||
}
|
||||
37
config/sketchybar/constants.lua
Normal file
37
config/sketchybar/constants.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
local events <const> = {
|
||||
AEROSPACE_WORKSPACE_CHANGED = 'aerospace_workspace_changed',
|
||||
AEROSPACE_SWITCH = 'aerospace_switch',
|
||||
SWAP_MENU_AND_SPACES = 'swap_menu_and_spaces',
|
||||
FRONT_APP_SWITCHED = 'front_app_switched',
|
||||
UPDATE_WINDOWS = 'update_windows',
|
||||
SEND_MESSAGE = 'send_message',
|
||||
HIDE_MESSAGE = 'hide_message',
|
||||
}
|
||||
|
||||
local items <const> = {
|
||||
SPACES = 'workspaces',
|
||||
MENU = 'menu',
|
||||
MENU_TOGGLE = 'menu_toggle',
|
||||
FRONT_APPS = 'front_apps',
|
||||
MESSAGE = 'message',
|
||||
VOLUME = 'widgets.volume',
|
||||
WIFI = 'widgets.wifi',
|
||||
BATTERY = 'widgets.battery',
|
||||
CALENDAR = 'widgets.calendar',
|
||||
}
|
||||
|
||||
local aerospace_cmd <const> = '/opt/homebrew/bin/aerospace'
|
||||
|
||||
local aerospace <const> = {
|
||||
LIST_ALL_WORKSPACES = aerospace_cmd .. ' list-workspaces --all',
|
||||
GET_CURRENT_WORKSPACE = aerospace_cmd .. ' list-workspaces --focused',
|
||||
LIST_WINDOWS = aerospace_cmd .. ' list-windows --workspace focused --format "id=%{window-id}, name=%{app-name}"',
|
||||
GET_CURRENT_WINDOW = aerospace_cmd .. ' list-windows --focused --format %{app-name}',
|
||||
}
|
||||
|
||||
return {
|
||||
items = items,
|
||||
events = events,
|
||||
aerospace_cmd = aerospace_cmd,
|
||||
aerospace = aerospace,
|
||||
}
|
||||
66
config/sketchybar/default.lua
Normal file
66
config/sketchybar/default.lua
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
local settings = require 'config.settings'
|
||||
|
||||
sbar.default {
|
||||
updates = 'when_shown',
|
||||
icon = {
|
||||
font = {
|
||||
family = settings.fonts.text,
|
||||
style = settings.fonts.styles.regular,
|
||||
size = settings.dimens.text.icon,
|
||||
},
|
||||
color = settings.colors.white,
|
||||
padding_left = settings.dimens.padding.icon,
|
||||
padding_right = settings.dimens.padding.icon,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.fonts.text,
|
||||
style = settings.fonts.styles.regular,
|
||||
size = settings.dimens.text.label,
|
||||
},
|
||||
color = settings.colors.white,
|
||||
padding_left = settings.dimens.padding.label,
|
||||
padding_right = settings.dimens.padding.label,
|
||||
},
|
||||
background = {
|
||||
height = settings.dimens.graphics.background.height,
|
||||
corner_radius = settings.dimens.graphics.background.corner_radius,
|
||||
border_width = 0,
|
||||
image = {
|
||||
corner_radius = settings.dimens.graphics.background.corner_radius,
|
||||
},
|
||||
},
|
||||
popup = {
|
||||
y_offset = settings.dimens.padding.popup,
|
||||
align = 'center',
|
||||
background = {
|
||||
border_width = 0,
|
||||
corner_radius = settings.dimens.graphics.background.corner_radius,
|
||||
color = settings.colors.popup.bg,
|
||||
shadow = { drawing = true },
|
||||
padding_left = settings.dimens.padding.icon,
|
||||
padding_right = settings.dimens.padding.icon,
|
||||
},
|
||||
blur_radius = settings.dimens.graphics.blur_radius,
|
||||
},
|
||||
slider = {
|
||||
highlight_color = settings.colors.orange,
|
||||
background = {
|
||||
height = settings.dimens.graphics.slider.height,
|
||||
corner_radius = settings.dimens.graphics.background.corner_radius,
|
||||
color = settings.colors.slider.bg,
|
||||
border_color = settings.colors.slider.border,
|
||||
border_width = 1,
|
||||
},
|
||||
knob = {
|
||||
font = {
|
||||
family = settings.fonts.text,
|
||||
style = settings.fonts.styles.regular,
|
||||
size = 32,
|
||||
},
|
||||
string = settings.icons.text.slider.knob,
|
||||
drawing = false,
|
||||
},
|
||||
},
|
||||
scroll_texts = true,
|
||||
}
|
||||
|
|
@ -1,56 +1,13 @@
|
|||
#!/usr/bin/env lua
|
||||
sbar = require 'sketchybar'
|
||||
|
||||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
sbar.default {
|
||||
updates = 'when_shown',
|
||||
icon = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Bold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
background = { image = { corner_radius = 9 } },
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Semibold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
},
|
||||
background = {
|
||||
height = 30,
|
||||
corner_radius = 12,
|
||||
border_width = 1,
|
||||
-- border_color = colors.bar.border,
|
||||
image = {
|
||||
corner_radius = 8,
|
||||
-- border_color = colors.grey,
|
||||
border_width = 1,
|
||||
},
|
||||
},
|
||||
popup = {
|
||||
background = {
|
||||
border_width = 1,
|
||||
corner_radius = 8,
|
||||
border_color = colors.popup.border,
|
||||
color = colors.popup.bg,
|
||||
shadow = { drawing = true },
|
||||
},
|
||||
blur_radius = 20,
|
||||
},
|
||||
padding_left = 5,
|
||||
padding_right = 5,
|
||||
scroll_texts = true,
|
||||
}
|
||||
sbar.begin_config()
|
||||
sbar.hotload(true)
|
||||
|
||||
require 'constants'
|
||||
require 'config'
|
||||
require 'bar'
|
||||
require 'default'
|
||||
require 'items'
|
||||
|
||||
sbar.end_config()
|
||||
sbar.event_loop()
|
||||
|
|
|
|||
|
|
@ -1,37 +1,7 @@
|
|||
local colors = require 'colors'
|
||||
local icons = require 'icons'
|
||||
local settings = require 'settings'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
-- 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 = settings.paddings,
|
||||
padding_left = 0,
|
||||
color = colors.fg,
|
||||
},
|
||||
local apple = sbar.add('item', 'apple', {
|
||||
icon = { string = settings.icons.text.apple },
|
||||
label = { drawing = false },
|
||||
background = {
|
||||
color = colors.bar.bg,
|
||||
-- border_color = colors.black,
|
||||
-- border_width = 1
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = 'sk-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 })
|
||||
|
|
|
|||
61
config/sketchybar/items/front_apps.lua
Normal file
61
config/sketchybar/items/front_apps.lua
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local frontApps = {}
|
||||
|
||||
sbar.add('bracket', constants.items.FRONT_APPS, {}, { position = 'left' })
|
||||
|
||||
local frontAppWatcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
local function selectFocusedWindow(frontAppName)
|
||||
for appName, app in pairs(frontApps) do
|
||||
local isSelected = appName == frontAppName
|
||||
local color = isSelected and settings.colors.orange or settings.colors.white
|
||||
app:set {
|
||||
label = { color = color },
|
||||
icon = { color = color },
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function updateWindows(windows)
|
||||
sbar.remove('/' .. constants.items.FRONT_APPS .. '\\.*/')
|
||||
|
||||
frontApps = {}
|
||||
local foundWindows = string.gmatch(windows, '[^\n]+')
|
||||
for window in foundWindows do
|
||||
local parsedWindow = {}
|
||||
for key, value in string.gmatch(window, '(%w+)=([%w%s]+)') do
|
||||
parsedWindow[key] = value
|
||||
end
|
||||
|
||||
local windowId = parsedWindow['id']
|
||||
local windowName = parsedWindow['name']
|
||||
local icon = settings.icons.apps[windowName] or settings.icons.apps['default']
|
||||
|
||||
frontApps[windowName] = sbar.add('item', constants.items.FRONT_APPS .. '.' .. windowName, {
|
||||
label = {
|
||||
padding_left = 0,
|
||||
string = windowName,
|
||||
},
|
||||
icon = {
|
||||
string = icon,
|
||||
font = settings.fonts.icons(),
|
||||
},
|
||||
click_script = constants.aerospace_cmd .. ' focus --window-id ' .. windowId,
|
||||
})
|
||||
|
||||
frontApps[windowName]:subscribe(constants.events.FRONT_APP_SWITCHED, function(env) selectFocusedWindow(env.INFO) end)
|
||||
end
|
||||
|
||||
sbar.exec(constants.aerospace.GET_CURRENT_WINDOW, function(frontAppName) selectFocusedWindow(frontAppName:gsub('[\n\r]', '')) end)
|
||||
end
|
||||
|
||||
local function getWindows() sbar.exec(constants.aerospace.LIST_WINDOWS, updateWindows) end
|
||||
|
||||
frontAppWatcher:subscribe(constants.events.UPDATE_WINDOWS, function() getWindows() end)
|
||||
|
||||
getWindows()
|
||||
|
|
@ -1,34 +1,12 @@
|
|||
local function file_exists(path)
|
||||
local f = io.open(path, 'r')
|
||||
if f then
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function load_module_if_program_exists(module_name, binary_path)
|
||||
if file_exists(binary_path) then
|
||||
print('Loading ' .. module_name .. ' (found at ' .. binary_path .. ')')
|
||||
local ok, err = pcall(require, module_name)
|
||||
if not ok then
|
||||
print('ERROR loading ' .. module_name .. ' module: ' .. tostring(err))
|
||||
else
|
||||
print('Successfully loaded ' .. module_name)
|
||||
end
|
||||
else
|
||||
print('Skipping ' .. module_name .. ' (binary not found at ' .. binary_path .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
-- Left items
|
||||
require 'items.apple'
|
||||
-- require 'items.aerospace'
|
||||
load_module_if_program_exists('items.aerospace', '/opt/homebrew/bin/aerospace')
|
||||
load_module_if_program_exists('items.yabai', '/etc/profiles/per-user/rayandrew/bin/yabai')
|
||||
require 'items.front_app'
|
||||
require 'items.menu'
|
||||
require 'items.battery'
|
||||
require 'items.cal'
|
||||
require 'items.volume'
|
||||
require 'items.cpu'
|
||||
require 'items.wifi'
|
||||
require 'items.menu_spaces_toggle'
|
||||
require 'items.menus'
|
||||
require 'items.spaces'
|
||||
require 'items.front_apps'
|
||||
|
||||
-- Right items
|
||||
require 'items.message'
|
||||
require 'items.widgets'
|
||||
|
||||
-- require("items.media")
|
||||
|
|
|
|||
75
config/sketchybar/items/menu_spaces_toggle.lua
Normal file
75
config/sketchybar/items/menu_spaces_toggle.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
sbar.add('event', constants.events.SWAP_MENU_AND_SPACES)
|
||||
|
||||
local function switchToggle(menuToggle)
|
||||
local isShowingMenu = menuToggle:query().icon.value == settings.icons.text.switch.on
|
||||
|
||||
menuToggle:set {
|
||||
icon = isShowingMenu and settings.icons.text.switch.off or settings.icons.text.switch.on,
|
||||
label = isShowingMenu and 'Menus' or 'Spaces',
|
||||
}
|
||||
|
||||
sbar.trigger(constants.events.SWAP_MENU_AND_SPACES, { isShowingMenu = isShowingMenu })
|
||||
end
|
||||
|
||||
local function addToggle()
|
||||
local menuToggle = sbar.add('item', constants.items.MENU_TOGGLE, {
|
||||
icon = {
|
||||
string = settings.icons.text.switch.on,
|
||||
},
|
||||
label = {
|
||||
width = 0,
|
||||
color = settings.colors.bg1,
|
||||
string = 'Spaces',
|
||||
},
|
||||
background = {
|
||||
color = settings.colors.with_alpha(settings.colors.dirty_white, 0.0),
|
||||
},
|
||||
})
|
||||
|
||||
sbar.add('item', constants.items.MENU_TOGGLE .. '.padding', {
|
||||
width = settings.dimens.padding.label,
|
||||
})
|
||||
|
||||
menuToggle:subscribe('mouse.entered', function(env)
|
||||
sbar.animate(
|
||||
'tanh',
|
||||
30,
|
||||
function()
|
||||
menuToggle:set {
|
||||
background = {
|
||||
color = { alpha = 1.0 },
|
||||
border_color = { alpha = 0.5 },
|
||||
},
|
||||
icon = { color = settings.colors.bg1 },
|
||||
label = { width = 'dynamic' },
|
||||
}
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
menuToggle:subscribe('mouse.exited', function(env)
|
||||
sbar.animate(
|
||||
'tanh',
|
||||
30,
|
||||
function()
|
||||
menuToggle:set {
|
||||
background = {
|
||||
color = { alpha = 0.0 },
|
||||
border_color = { alpha = 0.0 },
|
||||
},
|
||||
icon = { color = settings.colors.white },
|
||||
label = { width = 0 },
|
||||
}
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
menuToggle:subscribe('mouse.clicked', function(env) switchToggle(menuToggle) end)
|
||||
|
||||
menuToggle:subscribe(constants.events.AEROSPACE_SWITCH, function(env) switchToggle(menuToggle) end)
|
||||
end
|
||||
|
||||
addToggle()
|
||||
72
config/sketchybar/items/menus.lua
Normal file
72
config/sketchybar/items/menus.lua
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local maxItems <const> = 15
|
||||
local menuItems = {}
|
||||
local isShowingMenu = false
|
||||
|
||||
local frontAppWatcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
local swapWatcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
local function createPlaceholders()
|
||||
for index = 1, maxItems, 1 do
|
||||
local menu = sbar.add('item', constants.items.MENU .. '.' .. index, {
|
||||
drawing = false,
|
||||
icon = { drawing = false },
|
||||
width = 'dynamic',
|
||||
label = {
|
||||
font = {
|
||||
style = index == 1 and settings.fonts.styles.bold or settings.fonts.styles.regular,
|
||||
},
|
||||
},
|
||||
click_script = 'sk-menus -s ' .. index,
|
||||
})
|
||||
menuItems[index] = menu
|
||||
end
|
||||
|
||||
sbar.add('bracket', { '/' .. constants.items.MENU .. '\\..*/' }, {
|
||||
background = {
|
||||
color = settings.colors.bg1,
|
||||
padding_left = settings.dimens.padding.item,
|
||||
padding_right = settings.dimens.padding.item,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
local function updateMenus()
|
||||
sbar.set('/' .. constants.items.MENU .. '\\..*/', { drawing = false })
|
||||
|
||||
sbar.exec('sk-menus -l', function(menus)
|
||||
local index = 1
|
||||
for menu in string.gmatch(menus, '[^\r\n]+') do
|
||||
if index < maxItems then
|
||||
menuItems[index]:set {
|
||||
width = 'dynamic',
|
||||
label = menu,
|
||||
drawing = isShowingMenu,
|
||||
}
|
||||
else
|
||||
break
|
||||
end
|
||||
index = index + 1
|
||||
end
|
||||
end)
|
||||
|
||||
sbar.set(constants.items.MENU .. '.padding', { drawing = isShowingMenu })
|
||||
end
|
||||
|
||||
frontAppWatcher:subscribe(constants.events.FRONT_APP_SWITCHED, updateMenus)
|
||||
|
||||
swapWatcher:subscribe(constants.events.SWAP_MENU_AND_SPACES, function(env)
|
||||
isShowingMenu = env.isShowingMenu == 'on'
|
||||
updateMenus()
|
||||
end)
|
||||
|
||||
createPlaceholders()
|
||||
51
config/sketchybar/items/message.lua
Normal file
51
config/sketchybar/items/message.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local message = sbar.add('item', constants.items.MESSAGE, {
|
||||
width = 0,
|
||||
position = 'center',
|
||||
popup = { align = 'center' },
|
||||
label = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
},
|
||||
background = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
},
|
||||
})
|
||||
|
||||
local messagePopup = sbar.add('item', {
|
||||
position = 'popup.' .. message.name,
|
||||
width = 'dynamic',
|
||||
label = {
|
||||
padding_right = settings.dimens.padding.label,
|
||||
padding_left = settings.dimens.padding.label,
|
||||
},
|
||||
icon = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
},
|
||||
})
|
||||
|
||||
local function hideMessage() message:set { popup = { drawing = false } } end
|
||||
|
||||
local function showMessage(content, hold)
|
||||
hideMessage()
|
||||
|
||||
message:set { popup = { drawing = true } }
|
||||
messagePopup:set { label = { string = content } }
|
||||
|
||||
if hold == false then sbar.delay(5, function()
|
||||
if hold then return end
|
||||
hideMessage()
|
||||
end) end
|
||||
end
|
||||
|
||||
message:subscribe(constants.events.SEND_MESSAGE, function(env)
|
||||
local content = env.MESSAGE
|
||||
local hold = env.HOLD ~= nil and env.HOLD == 'true' or false
|
||||
showMessage(content, hold)
|
||||
end)
|
||||
|
||||
message:subscribe(constants.events.HIDE_MESSAGE, hideMessage)
|
||||
179
config/sketchybar/items/spaces.lua
Normal file
179
config/sketchybar/items/spaces.lua
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
local utils = require 'utils'
|
||||
|
||||
local spaces = {}
|
||||
local paddings = {}
|
||||
local focusedWorkspace = nil
|
||||
|
||||
local swapWatcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
local currentWorkspaceWatcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
-- Modify this file with Visual Studio Code - at least vim does have problems with the icons
|
||||
-- copy "Icons" from the nerd fonts cheat sheet and replace icon and name accordingly below
|
||||
-- https://www.nerdfonts.com/cheat-sheet
|
||||
local spaceConfigs <const> = {
|
||||
['1'] = { icon = '', name = 'Main' },
|
||||
['2'] = { icon = '', name = '' },
|
||||
['3'] = { icon = '', name = '' },
|
||||
['4'] = { icon = '', name = '' },
|
||||
['5'] = { icon = '', name = '' },
|
||||
['6'] = { icon = '', name = '' },
|
||||
['7'] = { icon = '', name = 'Music' },
|
||||
['8'] = { icon = '', name = 'Mail' },
|
||||
['9'] = { icon = '', name = 'Chat' },
|
||||
['10'] = { icon = '', name = 'Browser' },
|
||||
['t'] = { icon = '', name = 'Meeting' },
|
||||
}
|
||||
|
||||
-- Track which workspaces have windows
|
||||
local workspaceHasWindows = {}
|
||||
|
||||
local updateWorkspaceVisibility = utils.coro.async(function()
|
||||
local output = utils.coro.await(utils.coro.exec(constants.aerospace_cmd .. " list-windows --all --format '%{workspace}'"))
|
||||
|
||||
-- Reset all
|
||||
for ws, _ in pairs(workspaceHasWindows) do
|
||||
workspaceHasWindows[ws] = false
|
||||
end
|
||||
|
||||
-- Mark workspaces that have windows
|
||||
if output then
|
||||
for ws in output:gmatch '[^\r\n]+' do
|
||||
workspaceHasWindows[ws] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Update visibility for each space
|
||||
for workspaceName, _ in pairs(spaceConfigs) do
|
||||
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
||||
local space = spaces[spaceName]
|
||||
local padding = paddings[spaceName]
|
||||
|
||||
if space then
|
||||
local hasWindows = workspaceHasWindows[workspaceName] == true
|
||||
local isFocused = focusedWorkspace == workspaceName
|
||||
local shouldShow = hasWindows or isFocused
|
||||
|
||||
space:set { drawing = shouldShow }
|
||||
if padding then padding:set { drawing = shouldShow } end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function selectCurrentWorkspace(focusedWorkspaceName)
|
||||
focusedWorkspace = focusedWorkspaceName
|
||||
|
||||
for workspaceName, _ in pairs(spaceConfigs) do
|
||||
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
||||
local item = spaces[spaceName]
|
||||
local padding = paddings[spaceName]
|
||||
if item ~= nil then
|
||||
local isSelected = workspaceName == focusedWorkspaceName
|
||||
local hasWindows = workspaceHasWindows[workspaceName] == true
|
||||
local shouldShow = hasWindows or isSelected
|
||||
|
||||
-- Show/hide based on windows or focus
|
||||
item:set {
|
||||
drawing = shouldShow,
|
||||
icon = { color = isSelected and settings.colors.bg1 or settings.colors.white },
|
||||
label = { color = isSelected and settings.colors.bg1 or settings.colors.white },
|
||||
background = { color = isSelected and settings.colors.white or settings.colors.bg1 },
|
||||
}
|
||||
if padding then padding:set { drawing = shouldShow } end
|
||||
end
|
||||
end
|
||||
|
||||
updateWorkspaceVisibility()
|
||||
sbar.trigger(constants.events.UPDATE_WINDOWS)
|
||||
end
|
||||
|
||||
local findAndSelectCurrentWorkspace = utils.coro.async(function()
|
||||
local focusedWorkspaceOutput = utils.coro.await(utils.coro.exec(constants.aerospace.GET_CURRENT_WORKSPACE))
|
||||
if focusedWorkspaceOutput then
|
||||
local focusedWorkspaceName = focusedWorkspaceOutput:match '[^\r\n]+'
|
||||
selectCurrentWorkspace(focusedWorkspaceName)
|
||||
end
|
||||
end)
|
||||
|
||||
local function addWorkspaceItem(workspaceName)
|
||||
local spaceName = constants.items.SPACES .. '.' .. workspaceName
|
||||
local spaceConfig = spaceConfigs[workspaceName]
|
||||
|
||||
-- Skip workspaces without a config entry
|
||||
if not spaceConfig then return end
|
||||
|
||||
local hasIcon = spaceConfig.icon and spaceConfig.icon ~= ''
|
||||
local hasName = spaceConfig.name and spaceConfig.name ~= ''
|
||||
local icon = hasIcon and spaceConfig.icon or workspaceName
|
||||
local name = hasName and spaceConfig.name or workspaceName
|
||||
local useBold = not hasIcon
|
||||
local fontStyle = useBold and settings.fonts.styles.bold or settings.fonts.styles.regular
|
||||
local iconFont = settings.fonts.text .. ':' .. fontStyle .. ':' .. settings.dimens.text.icon
|
||||
|
||||
spaces[spaceName] = sbar.add('item', spaceName, {
|
||||
drawing = false, -- start hidden, will show if has windows or is focused
|
||||
label = {
|
||||
width = 0,
|
||||
padding_left = 0,
|
||||
string = name,
|
||||
},
|
||||
icon = {
|
||||
string = icon,
|
||||
font = iconFont,
|
||||
color = settings.colors.white,
|
||||
y_offset = useBold and 1 or 0,
|
||||
},
|
||||
background = {
|
||||
color = settings.colors.bg1,
|
||||
},
|
||||
click_script = constants.aerospace_cmd .. ' workspace ' .. workspaceName,
|
||||
})
|
||||
|
||||
spaces[spaceName]:subscribe('mouse.entered', function(env)
|
||||
sbar.animate('tanh', 30, function() spaces[spaceName]:set { label = { width = 'dynamic' } } end)
|
||||
end)
|
||||
|
||||
spaces[spaceName]:subscribe('mouse.exited', function(env)
|
||||
sbar.animate('tanh', 30, function() spaces[spaceName]:set { label = { width = 0 } } end)
|
||||
end)
|
||||
|
||||
paddings[spaceName] = sbar.add('item', spaceName .. '.padding', {
|
||||
drawing = false,
|
||||
width = settings.dimens.padding.label,
|
||||
})
|
||||
end
|
||||
|
||||
local createWorkspaces = utils.coro.async(function()
|
||||
local workspacesOutput = utils.coro.await(utils.coro.exec(constants.aerospace.LIST_ALL_WORKSPACES))
|
||||
if workspacesOutput then
|
||||
for workspaceName in workspacesOutput:gmatch '[^\r\n]+' do
|
||||
addWorkspaceItem(workspaceName)
|
||||
end
|
||||
end
|
||||
|
||||
findAndSelectCurrentWorkspace()
|
||||
end)
|
||||
|
||||
swapWatcher:subscribe(constants.events.SWAP_MENU_AND_SPACES, function(env)
|
||||
local isShowingSpaces = env.isShowingMenu == 'off' and true or false
|
||||
if isShowingSpaces then
|
||||
updateWorkspaceVisibility()
|
||||
else
|
||||
sbar.set('/' .. constants.items.SPACES .. '\\..*/', { drawing = false })
|
||||
end
|
||||
end)
|
||||
|
||||
currentWorkspaceWatcher:subscribe(constants.events.AEROSPACE_WORKSPACE_CHANGED, function(env) selectCurrentWorkspace(env.FOCUSED_WORKSPACE) end)
|
||||
|
||||
-- Also update on window changes
|
||||
currentWorkspaceWatcher:subscribe('front_app_switched', function(env) updateWorkspaceVisibility() end)
|
||||
|
||||
createWorkspaces()
|
||||
89
config/sketchybar/items/widgets/battery.lua
Normal file
89
config/sketchybar/items/widgets/battery.lua
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local isCharging = false
|
||||
|
||||
local battery = sbar.add('item', constants.items.battery, {
|
||||
position = 'right',
|
||||
update_freq = 60,
|
||||
})
|
||||
|
||||
local batteryPopup = sbar.add('item', {
|
||||
position = 'popup.' .. battery.name,
|
||||
width = 'dynamic',
|
||||
label = {
|
||||
padding_right = settings.dimens.padding.label,
|
||||
padding_left = settings.dimens.padding.label,
|
||||
},
|
||||
icon = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
},
|
||||
})
|
||||
|
||||
battery:subscribe({ 'routine', 'power_source_change', 'system_woke' }, function()
|
||||
sbar.exec('pmset -g batt', function(batteryInfo)
|
||||
local icon = '!'
|
||||
local label = '?'
|
||||
|
||||
local found, _, charge = batteryInfo:find '(%d+)%%'
|
||||
if found then
|
||||
charge = tonumber(charge)
|
||||
label = charge .. '%'
|
||||
end
|
||||
|
||||
local color = settings.colors.green
|
||||
local charging, _, _ = batteryInfo:find 'AC Power'
|
||||
|
||||
isCharging = charging
|
||||
|
||||
if charging then
|
||||
icon = settings.icons.text.battery.charging
|
||||
else
|
||||
if found and charge > 80 then
|
||||
icon = settings.icons.text.battery._100
|
||||
elseif found and charge > 60 then
|
||||
icon = settings.icons.text.battery._75
|
||||
elseif found and charge > 40 then
|
||||
icon = settings.icons.text.battery._50
|
||||
elseif found and charge > 30 then
|
||||
icon = settings.icons.text.battery._50
|
||||
color = settings.colors.yellow
|
||||
elseif found and charge > 20 then
|
||||
icon = settings.icons.text.battery._25
|
||||
color = settings.colors.orange
|
||||
else
|
||||
icon = settings.icons.text.battery._0
|
||||
color = settings.colors.red
|
||||
end
|
||||
end
|
||||
|
||||
local lead = ''
|
||||
if found and charge < 10 then lead = '0' end
|
||||
|
||||
battery:set {
|
||||
icon = {
|
||||
string = icon,
|
||||
color = color,
|
||||
},
|
||||
label = {
|
||||
string = lead .. label,
|
||||
padding_left = 0,
|
||||
},
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
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(batteryInfo)
|
||||
local found, _, remaining = batteryInfo:find '(%d+:%d+) remaining'
|
||||
local label = found and ('Time remaining: ' .. remaining .. 'h') or (isCharging and 'Charging' or 'No estimate')
|
||||
batteryPopup:set { label = label }
|
||||
end)
|
||||
end
|
||||
end)
|
||||
15
config/sketchybar/items/widgets/calendar.lua
Normal file
15
config/sketchybar/items/widgets/calendar.lua
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
local constants = require 'constants'
|
||||
|
||||
local calendar = sbar.add('item', constants.items.CALENDAR, {
|
||||
position = 'right',
|
||||
update_freq = 1,
|
||||
icon = { padding_left = 0, padding_right = 0 },
|
||||
})
|
||||
|
||||
calendar:subscribe({ 'forced', 'routine', 'system_woke' }, function(env)
|
||||
calendar:set {
|
||||
label = os.date '%a %d %b, %H:%M',
|
||||
}
|
||||
end)
|
||||
|
||||
calendar:subscribe('mouse.clicked', function(env) sbar.exec "open -a 'Calendar'" end)
|
||||
4
config/sketchybar/items/widgets/init.lua
Normal file
4
config/sketchybar/items/widgets/init.lua
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
require 'items.widgets.calendar'
|
||||
require 'items.widgets.battery'
|
||||
require 'items.widgets.volume'
|
||||
require 'items.widgets.wifi'
|
||||
127
config/sketchybar/items/widgets/volume.lua
Normal file
127
config/sketchybar/items/widgets/volume.lua
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local currentAudioDevice = 'None'
|
||||
|
||||
local volumeValue = sbar.add('item', constants.items.VOLUME .. '.value', {
|
||||
position = 'right',
|
||||
label = {
|
||||
string = '??%',
|
||||
padding_left = 0,
|
||||
},
|
||||
})
|
||||
|
||||
local volumeBracket = sbar.add('bracket', constants.items.VOLUME .. '.bracket', { volumeValue.name }, {
|
||||
popup = {
|
||||
align = 'center',
|
||||
},
|
||||
})
|
||||
|
||||
local volumeSlider = sbar.add('slider', constants.items.VOLUME .. '.slider', settings.dimens.graphics.popup.width, {
|
||||
position = 'popup.' .. volumeBracket.name,
|
||||
click_script = 'osascript -e "set volume output volume $PERCENTAGE"',
|
||||
})
|
||||
|
||||
volumeValue:subscribe('volume_change', function(env)
|
||||
local icon = settings.icons.text.volume._0
|
||||
local volume = tonumber(env.INFO)
|
||||
|
||||
sbar.exec('SwitchAudioSource -t output -c', function(result)
|
||||
-- local currentOutputDevice = result:sub(1, -2)
|
||||
-- if currentOutputDevice == "AirPods Max" then
|
||||
-- icon = ""
|
||||
-- elseif currentOutputDevice == "AirPods von Longdong Silver" or currentOutputDevice == "AirPods von Anna" then
|
||||
-- icon = ""
|
||||
-- elseif currentOutputDevice == "Arctis Nova Pro Wireless" then
|
||||
-- icon = ""
|
||||
-- elseif currentOutputDevice == "Ear (2)" then
|
||||
-- icon = ""
|
||||
-- elseif currentOutputDevice == "iD4" then
|
||||
-- icon = ""
|
||||
-- else
|
||||
if volume > 60 then
|
||||
icon = settings.icons.text.volume._100
|
||||
elseif volume > 30 then
|
||||
icon = settings.icons.text.volume._66
|
||||
elseif volume > 10 then
|
||||
icon = settings.icons.text.volume._33
|
||||
elseif volume > 0 then
|
||||
icon = settings.icons.text.volume._10
|
||||
end
|
||||
-- end
|
||||
|
||||
local lead = ''
|
||||
if volume < 10 then lead = '0' end
|
||||
|
||||
-- volumeIcon:set({ label = icon })
|
||||
volumeSlider:set { slider = { percentage = volume } }
|
||||
|
||||
local hasVolume = volume ~= 0
|
||||
volumeValue:set {
|
||||
icon = icon,
|
||||
label = {
|
||||
string = hasVolume and lead .. volume .. '%' or '',
|
||||
padding_right = hasVolume and 8 or 0,
|
||||
},
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
local function hideVolumeDetails()
|
||||
local drawing = volumeBracket:query().popup.drawing == 'on'
|
||||
if not drawing then return end
|
||||
volumeBracket:set { popup = { drawing = false } }
|
||||
sbar.remove('/' .. constants.items.VOLUME .. '.device\\.*/')
|
||||
end
|
||||
|
||||
local function toggleVolumeDetails(env)
|
||||
if env.BUTTON == 'right' then
|
||||
sbar.exec 'open /System/Library/PreferencePanes/Sound.prefpane'
|
||||
return
|
||||
end
|
||||
|
||||
local shouldDraw = volumeBracket:query().popup.drawing == 'off'
|
||||
if shouldDraw then
|
||||
volumeBracket:set { popup = { drawing = true } }
|
||||
|
||||
sbar.exec('SwitchAudioSource -t output -c', function(result)
|
||||
currentAudioDevice = result:sub(1, -2)
|
||||
|
||||
sbar.exec('SwitchAudioSource -a -t output', function(available)
|
||||
local current = currentAudioDevice
|
||||
local counter = 0
|
||||
|
||||
for device in string.gmatch(available, '[^\r\n]+') do
|
||||
local color = settings.colors.grey
|
||||
if current == device then color = settings.colors.white end
|
||||
|
||||
sbar.add('item', constants.items.VOLUME .. '.device.' .. counter, {
|
||||
position = 'popup.' .. volumeBracket.name,
|
||||
align = 'center',
|
||||
label = { string = device, color = color },
|
||||
click_script = 'SwitchAudioSource -s "'
|
||||
.. device
|
||||
.. '" && sketchybar --set /'
|
||||
.. constants.items.VOLUME
|
||||
.. '.device\\.*/ label.color='
|
||||
.. settings.colors.grey
|
||||
.. ' --set $NAME label.color='
|
||||
.. settings.colors.white,
|
||||
})
|
||||
counter = counter + 1
|
||||
end
|
||||
end)
|
||||
end)
|
||||
else
|
||||
hideVolumeDetails()
|
||||
end
|
||||
end
|
||||
|
||||
local function changeVolume(env)
|
||||
local delta = env.SCROLL_DELTA
|
||||
sbar.exec('osascript -e "set volume output volume (output volume of (get volume settings) + ' .. delta .. ')"')
|
||||
end
|
||||
|
||||
volumeValue:subscribe('mouse.clicked', toggleVolumeDetails)
|
||||
volumeValue:subscribe('mouse.scrolled', changeVolume)
|
||||
-- volumeValue:subscribe("mouse.exited.global", hideVolumeDetails)
|
||||
247
config/sketchybar/items/widgets/wifi.lua
Normal file
247
config/sketchybar/items/widgets/wifi.lua
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
local constants = require 'constants'
|
||||
local settings = require 'config.settings'
|
||||
|
||||
local popupWidth <const> = settings.dimens.graphics.popup.width + 20
|
||||
|
||||
sbar.exec 'killall sk-network-load >/dev/null; sk-network-load en0 network_update 2.0'
|
||||
|
||||
local wifiUp = sbar.add('item', constants.items.WIFI .. '.up', {
|
||||
position = 'right',
|
||||
width = 0,
|
||||
icon = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.fonts.styles.bold,
|
||||
size = 10.0,
|
||||
},
|
||||
string = settings.icons.text.wifi.upload,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.fonts.numbers,
|
||||
style = settings.fonts.styles.bold,
|
||||
size = 10.0,
|
||||
},
|
||||
color = settings.colors.orange,
|
||||
string = '??? Bps',
|
||||
},
|
||||
y_offset = 4,
|
||||
})
|
||||
|
||||
local wifiDown = sbar.add('item', constants.items.WIFI .. '.down', {
|
||||
position = 'right',
|
||||
icon = {
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.fonts.styles.bold,
|
||||
size = 10.0,
|
||||
},
|
||||
string = settings.icons.text.wifi.download,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.fonts.numbers,
|
||||
style = settings.fonts.styles.bold,
|
||||
size = 10,
|
||||
},
|
||||
color = settings.colors.blue,
|
||||
string = '??? Bps',
|
||||
},
|
||||
y_offset = -4,
|
||||
})
|
||||
|
||||
local wifi = sbar.add('item', constants.items.WIFI .. '.padding', {
|
||||
position = 'right',
|
||||
label = { drawing = false },
|
||||
padding_right = 0,
|
||||
})
|
||||
|
||||
local wifiBracket = sbar.add('bracket', constants.items.WIFI .. '.bracket', {
|
||||
wifi.name,
|
||||
wifiUp.name,
|
||||
wifiDown.name,
|
||||
}, {
|
||||
popup = { align = 'center' },
|
||||
})
|
||||
|
||||
local ssid = sbar.add('item', {
|
||||
align = 'center',
|
||||
position = 'popup.' .. wifiBracket.name,
|
||||
width = popupWidth,
|
||||
height = 16,
|
||||
icon = {
|
||||
string = settings.icons.text.wifi.router,
|
||||
font = {
|
||||
style = settings.fonts.styles.bold,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
style = settings.fonts.styles.bold,
|
||||
size = settings.dimens.text.label,
|
||||
},
|
||||
max_chars = 18,
|
||||
string = '????????????',
|
||||
},
|
||||
})
|
||||
|
||||
local hostname = sbar.add('item', {
|
||||
position = 'popup.' .. wifiBracket.name,
|
||||
background = {
|
||||
height = 16,
|
||||
},
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'Hostname:',
|
||||
width = popupWidth / 2,
|
||||
font = {
|
||||
size = settings.dimens.text.label,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
max_chars = 20,
|
||||
string = '????????????',
|
||||
width = popupWidth / 2,
|
||||
align = 'right',
|
||||
},
|
||||
})
|
||||
|
||||
local ip = sbar.add('item', {
|
||||
position = 'popup.' .. wifiBracket.name,
|
||||
background = {
|
||||
height = 16,
|
||||
},
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'IP:',
|
||||
width = popupWidth / 2,
|
||||
font = {
|
||||
size = settings.dimens.text.label,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
align = 'right',
|
||||
string = '???.???.???.???',
|
||||
width = popupWidth / 2,
|
||||
},
|
||||
})
|
||||
|
||||
local router = sbar.add('item', {
|
||||
position = 'popup.' .. wifiBracket.name,
|
||||
background = {
|
||||
height = 16,
|
||||
},
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'Router:',
|
||||
width = popupWidth / 2,
|
||||
font = {
|
||||
size = settings.dimens.text.label,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
align = 'right',
|
||||
string = '???.???.???.???',
|
||||
width = popupWidth / 2,
|
||||
},
|
||||
})
|
||||
|
||||
sbar.add('item', { position = 'right', width = settings.dimens.padding.item })
|
||||
|
||||
wifiUp:subscribe('network_update', function(env)
|
||||
local upColor = (env.upload == '000 Bps') and settings.colors.grey or settings.colors.orange
|
||||
local downColor = (env.download == '000 Bps') and settings.colors.grey or settings.colors.blue
|
||||
|
||||
wifiUp:set {
|
||||
icon = { color = upColor },
|
||||
label = {
|
||||
string = env.upload,
|
||||
color = upColor,
|
||||
},
|
||||
}
|
||||
wifiDown:set {
|
||||
icon = { color = downColor },
|
||||
label = {
|
||||
string = env.download,
|
||||
color = downColor,
|
||||
},
|
||||
}
|
||||
end)
|
||||
|
||||
wifi:subscribe({ 'wifi_change', 'system_woke', 'forced' }, function(env)
|
||||
wifi:set {
|
||||
icon = {
|
||||
string = settings.icons.text.wifi.disconnected,
|
||||
color = settings.colors.magenta,
|
||||
},
|
||||
}
|
||||
|
||||
sbar.exec([[ipconfig getifaddr en0]], function(ip)
|
||||
local ipConnected = not (ip == '')
|
||||
|
||||
local wifiIcon
|
||||
local wifiColor
|
||||
|
||||
if ipConnected then
|
||||
wifiIcon = settings.icons.text.wifi.connected
|
||||
wifiColor = settings.colors.white
|
||||
end
|
||||
|
||||
wifi:set {
|
||||
icon = {
|
||||
string = wifiIcon,
|
||||
color = wifiColor,
|
||||
},
|
||||
}
|
||||
|
||||
sbar.exec([[sleep 2; scutil --nwi | grep -m1 'utun' | awk '{ print $1 }']], function(vpn)
|
||||
local isVPNConnected = not (vpn == '')
|
||||
|
||||
if isVPNConnected then
|
||||
wifiIcon = settings.icons.text.wifi.vpn
|
||||
wifiColor = settings.colors.green
|
||||
end
|
||||
|
||||
wifi:set {
|
||||
icon = {
|
||||
string = wifiIcon,
|
||||
color = wifiColor,
|
||||
},
|
||||
}
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
local function hideDetails() wifiBracket:set { popup = { drawing = false } } end
|
||||
|
||||
local function toggleDetails()
|
||||
local shouldDrawDetails = wifiBracket:query().popup.drawing == 'off'
|
||||
|
||||
if shouldDrawDetails then
|
||||
wifiBracket: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 'Router: ' '/^Router: / {print $2}'", function(result) router:set { label = result } end)
|
||||
else
|
||||
hideDetails()
|
||||
end
|
||||
end
|
||||
|
||||
local function copyLabelToClipboard(env)
|
||||
local label = sbar.query(env.NAME).label.value
|
||||
sbar.exec('echo "' .. label .. '" | pbcopy')
|
||||
sbar.set(env.NAME, { label = { string = settings.icons.text.clipboard, align = 'center' } })
|
||||
sbar.delay(1, function() sbar.set(env.NAME, { label = { string = label, align = 'right' } }) end)
|
||||
end
|
||||
|
||||
wifiUp:subscribe('mouse.clicked', toggleDetails)
|
||||
wifiDown:subscribe('mouse.clicked', toggleDetails)
|
||||
wifi:subscribe('mouse.clicked', toggleDetails)
|
||||
|
||||
ssid:subscribe('mouse.clicked', copyLabelToClipboard)
|
||||
hostname:subscribe('mouse.clicked', copyLabelToClipboard)
|
||||
ip:subscribe('mouse.clicked', copyLabelToClipboard)
|
||||
router:subscribe('mouse.clicked', copyLabelToClipboard)
|
||||
67
config/sketchybar/utils/coro.lua
Normal file
67
config/sketchybar/utils/coro.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
local M = {}
|
||||
|
||||
-- Coroutine-based async/await helpers
|
||||
function M.await(callback_fn)
|
||||
local co = coroutine.running()
|
||||
if not co then error 'await must be called inside async' end
|
||||
|
||||
local result, err
|
||||
local done = false
|
||||
|
||||
callback_fn(function(res, e)
|
||||
result = res
|
||||
err = e
|
||||
done = true
|
||||
if coroutine.status(co) == 'suspended' then coroutine.resume(co) end
|
||||
end)
|
||||
|
||||
if not done then coroutine.yield() end
|
||||
if err then error(err) end
|
||||
return result
|
||||
end
|
||||
|
||||
function M.awaitAll(callback_fns)
|
||||
local co = coroutine.running()
|
||||
if not co then error 'awaitAll must be called inside async' end
|
||||
|
||||
local results = {}
|
||||
local pending = #callback_fns
|
||||
local err = nil
|
||||
|
||||
for i, fn in ipairs(callback_fns) do
|
||||
fn(function(res, e)
|
||||
if e then err = e end
|
||||
results[i] = res
|
||||
pending = pending - 1
|
||||
if pending == 0 and coroutine.status(co) == 'suspended' then coroutine.resume(co) end
|
||||
end)
|
||||
end
|
||||
|
||||
if pending > 0 then coroutine.yield() end
|
||||
if err then error(err) end
|
||||
return results
|
||||
end
|
||||
|
||||
function M.async(fn)
|
||||
return function(...)
|
||||
local args = { ... }
|
||||
local co = coroutine.create(function() fn(table.unpack(args)) end)
|
||||
local ok, err = coroutine.resume(co)
|
||||
if not ok then print('Async error: ' .. tostring(err)) end
|
||||
end
|
||||
end
|
||||
|
||||
-- Execute a shell command, returns a callback function for use with await
|
||||
function M.exec(cmd)
|
||||
return function(resolve)
|
||||
sbar.exec(cmd, function(result, exit_code)
|
||||
if exit_code ~= 0 then
|
||||
resolve(nil, string.format('Exit Code: %s Message: %s', tostring(exit_code), M.dump(result)))
|
||||
else
|
||||
resolve(result, nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
5
config/sketchybar/utils/init.lua
Normal file
5
config/sketchybar/utils/init.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
local coro <const> = require 'utils.coro'
|
||||
|
||||
return {
|
||||
coro = coro,
|
||||
}
|
||||
|
|
@ -25,9 +25,11 @@ in
|
|||
enable = true;
|
||||
# active_color = "0xFFA1EFE4";
|
||||
# inactive_color = "0xFFd3b58d";
|
||||
active_color = "0xFFFFFFFF";
|
||||
inactive_color = "0xFF000000";
|
||||
width = 5.0;
|
||||
# active_color = "0xFFFFFFFF";
|
||||
# inactive_color = "0xFF000000";
|
||||
active_color = "0xFFFFBE69";
|
||||
inactive_color = "0xFF007692";
|
||||
width = 8.0;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue