Share your plugins #12
Replies: 101 comments 344 replies
-
Window TitleDESCRIPTION: This will display the current window's title in your bar. If the window's title is greater than 50 characters it will truncate it, if there it no title available it will fall back to the application name. This was written by @FelixKratz and Modified by me. NOTE: Assuming you are using yabai, you can quickly check window titles and app names of the current window with Updated Configuration: sketchybarrc# E V E N T S
sketchybar -m --add event window_focus \
--add event title_change
# W I N D O W T I T L E
sketchybar -m --add item title left \
--set title script="$HOME/.config/sketchybar/plugins/window_title.sh" \
--subscribe title window_focus front_app_switched space_change title_change window_title.sh#!/bin/bash
# W I N D O W T I T L E
WINDOW_TITLE=$(/opt/homebrew/bin/yabai -m query --windows --window | jq -r '.title')
if [[ $WINDOW_TITLE = "" ]]; then
WINDOW_TITLE=$(/opt/homebrew/bin/yabai -m query --windows --window | jq -r '.app')
fi
if [[ ${#WINDOW_TITLE} -gt 50 ]]; then
WINDOW_TITLE=$(echo "$WINDOW_TITLE" | cut -c 1-50)
sketchybar -m --set title label="│ $WINDOW_TITLE"…
exit 0
fi
sketchybar -m --set title label="│ $WINDOW_TITLE" yabairc # S K E T C H Y B A R E V E N T S
yabai -m signal --add event=window_focused action="sketchybar -m --trigger window_focus &> /dev/null"
yabai -m signal --add event=window_title_changed action="sketchybar -m --trigger title_change &> /dev/null" |
Beta Was this translation helpful? Give feedback.
-
24 Hour Change in Bitcoin PriceDESCRIPTION: This will display the 24hr change in price of bitcoin in your bar. sketchybarrcsketchybar -m --add item btc right \
--set btc icon= \
--set btc update_freq=20 \
--set btc script="~/.config/sketchybar/plugins/btc.sh" btc.sh#!/usr/bin/env python3
import requests
import os
response = requests.get('https://api.gemini.com/v1/pricefeed')
jsonResponse = response.json()
for i in jsonResponse:
if i["pair"] == "BTCUSD":
percentChange = str(round((float(i["percentChange24h"]) * 100), 2))
os.system('sketchybar -m --set btc label='+ percentChange + '%')
break |
Beta Was this translation helpful? Give feedback.
-
24 Hour Change in Ethereum PriceDESCRIPTION: This will display the 24hr change in price of Ethereum in your bar. sketchybarrcsketchybarrcsketchybar -m --add item eth right \
--set eth icon=ﲹ \
--set eth update_freq=20 \
--set eth script="~/.config/sketchybar/plugins/eth.sh" eth.sh#!/usr/bin/env python3
import requests
import os
response = requests.get('https://api.gemini.com/v1/pricefeed')
jsonResponse = response.json()
for i in jsonResponse:
if i["pair"] == "BTCUSD":
percentChange = str(round((float(i["percentChange24h"]) * 100), 2))
os.system('sketchybar -m --set eth label='+ percentChange + '%')
break |
Beta Was this translation helpful? Give feedback.
-
Battery StatusDESCRIPTION: This will display your current battery status. NOTE: This could probably be improved on greatly. I am not sure what an appropriate UPDATED: Updated to implement improvements made by ut0mt8 from this comment. sketchybarrcsketchybar -m --add item battery right \
--set battery update_freq=3 \
--set battery script="~/.config/sketchybar/plugins/power.sh" \
--set battery icon= power.sh#!/bin/bash
. ~/.cache/wal/colors.sh
BATT_PERCENT=$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1)
CHARGING=$(pmset -g batt | grep 'AC Power')
if [[ $CHARGING != "" ]]; then
sketchybar -m --set battery \
icon.color=0xFF5DFE67 \
icon= \
label=$(printf "${BATT_PERCENT}%%")
exit 0
fi
[[ ${BATT_PERCENT} -gt 10 ]] && COLOR=0xFF${color5:1} || COLOR=0xFFFF0000
case ${BATT_PERCENT} in
100) ICON="" ;;
9[0-9]) ICON="" ;;
8[0-9]) ICON="" ;;
7[0-9]) ICON="" ;;
6[0-9]) ICON="" ;;
5[0-9]) ICON="" ;;
4[0-9]) ICON="" ;;
3[0-9]) ICON="" ;;
2[0-9]) ICON="" ;;
1[0-9]) ICON="" ;;
*) ICON=""
esac
sketchybar -m --set battery\
icon.color=$COLOR \
icon=$ICON \
label=$(printf "${BATT_PERCENT}%%") |
Beta Was this translation helpful? Give feedback.
-
Music InformationUpdate History:
DESCRIPTION: This will display information about the current track in the Music.app. It will update based on the NSDistributedNotificationCenter Events sent by the Music app. sketchybarrc# Add event
sketchybar -m --add event song_update com.apple.iTunes.playerInfo
# Add Music Item
sketchybar -m --add item music right \
--set music script="~/.config/sketchybar/scripts/music" \
click_script="~/.config/sketchybar/scripts/music_click" \
label.padding_right=10 \
drawing=off \
--subscribe music song_update music#!/usr/bin/env bash
# FIXME: Running an osascript on an application target opens that app
# This sleep is needed to try and ensure that theres enough time to
# quit the app before the next osascript command is called. I assume
# com.apple.iTunes.playerInfo fires off an event when the player quits
# so it imediately runs before the process is killed
sleep 1
APP_STATE=$(pgrep -x Music)
if [[ ! $APP_STATE ]]; then
sketchybar -m --set music drawing=off
exit 0
fi
PLAYER_STATE=$(osascript -e "tell application \"Music\" to set playerState to (get player state) as text")
if [[ $PLAYER_STATE == "stopped" ]]; then
sketchybar --set music drawing=off
exit 0
fi
title=$(osascript -e 'tell application "Music" to get name of current track')
artist=$(osascript -e 'tell application "Music" to get artist of current track')
# ALBUM=$(osascript -e 'tell application "Music" to get album of current track')
loved=$(osascript -l JavaScript -e "Application('Music').currentTrack().loved()")
if [[ $loved ]]; then
icon=""
fi
if [[ $PLAYER_STATE == "paused" ]]; then
icon=""
fi
if [[ $PLAYER_STATE == "playing" ]]; then
icon=""
fi
if [[ ${#title} -gt 25 ]]; then
TITLE=$(printf "$(echo $title | cut -c 1-25)…")
fi
if [[ ${#artist} -gt 25 ]]; then
ARTIST=$(printf "$(echo $artist | cut -c 1-25)…")
fi
# if [[ ${#ALBUM} -gt 25 ]]; then
# ALBUM=$(printf "$(echo $ALBUM | cut -c 1-12)…")
# fi
sketchybar -m --set music icon="$icon" \
--set music label="${title} x ${artist}" \
--set music drawing=on
music_click#!/usr/bin/env osascript
tell application "Music"
if loved of current track is true then
set loved of current track to false
do shell script "sketchybar -m --set music icon="
else
set loved of current track to true
do shell script "sketchybar -m --set music icon="
end if
end tell
delay 1
do shell script "sh $HOME/.config/sketchybar/scripts/music" |
Beta Was this translation helpful? Give feedback.
-
VPN StatusDESCRIPTION: Shows the vpn your currently connected to if any in your bar. sketchybarrcsketchybar -m --add item vpn right \
--set vpn icon= \
update_freq=5 \
script="~/.config/sketchybar/plugins/vpn.sh" vpn.sh#!/bin/bash
VPN=$(scutil --nc list | grep Connected | sed -E 's/.*"(.*)".*/\1/')
if [[ $VPN != "" ]]; then
sketchybar -m --set vpn icon= \
label="$VPN" \
drawing=on
else
sketchybar -m --set vpn drawing=off
fi |
Beta Was this translation helpful? Give feedback.
-
Mic StatusDESCRIPTION: Check and Mute/Unmute your mic. sketchybarrcsketchybar -m --add item mic right \
sketchybar -m --set mic update_freq=3 \
--set mic script="~/.config/sketchybar/plugins/mic.sh" \
--set mic click_script="~/.config/sketchybar/plugins/mic_click.sh" mic.sh#!/bin/bash
MIC_VOLUME=$(osascript -e 'input volume of (get volume settings)')
if [[ $MIC_VOLUME -eq 0 ]]; then
sketchybar -m --set mic icon=
elif [[ $MIC_VOLUME -gt 0 ]]; then
sketchybar -m --set mic icon=
fi
mic_click.sh#!/bin/bash
MIC_VOLUME=$(osascript -e 'input volume of (get volume settings)')
if [[ $MIC_VOLUME -eq 0 ]]; then
osascript -e 'set volume input volume 25'
sketchybar -m --set mic icon=
elif [[ $MIC_VOLUME -gt 0 ]]; then
osascript -e 'set volume input volume 0'
sketchybar -m --set mic icon=
fi |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
RemindersDESCRIPTION: Show your reminders. NOTE: This is just a very basic script, but it could be extended to show the reminder, or use a different app like taskwarrior or taskell instead. sketchybarrcsketchybar -m --add item reminders right \
--set reminders update_freq=20 \
--set reminders script="~/.config/sketchybar/plugins/reminders.sh" \
--set reminders click_script="~/.config/sketchybar/plugins/reminders_click.sh" reminders.sh#!/bin/bash
REMINDERS_COUNT=$(osascript -l JavaScript -e "Application('Reminders').lists.byName('📥 Inbox').reminders.whose({completed: false}).name().length")
if [[ $REMINDERS_COUNT -gt 0 ]]; then
sketchybar -m --set reminders icon="" \
--set reminders label="$REMINDERS_COUNT"
else
sketchybar -m --set reminders icon="" \
--set reminders label=""
fi reminders_click.sh#!/bin/bash
open -a Reminders |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Stack IndicatorDESCRIPTION: Show you Window's Stack Position. NOTE: Occasionally querying yabai can be delayed possibly related to this, which can lead to a number or dot being displayed late and overwriting the actual position in the indicator. sketchybarrc# S T A C K I N D I C A T O R
sketchybar -m --add item stack_sep center \
--add item stack center \
--set stack script="$HOME/.dotfiles/sketchybar/plugins/stack.sh" \
--subscribe stack window_focus front_app_switched space_change title_change \
--set stack_sep drawing=off \
--set stack drawing=off \
--set stack update_freq=0 stack.sh#!/bin/bash
# Exit if Not in Stack
CURRENT=$(yabai -m query --windows --window | jq '.["stack-index"]')
if [[ $CURRENT -eq 0 ]]; then
sketchybar -m --set stack label="" \
--set stack_sep drawing=off \
--set stack drawing=off
exit 0
fi
# Use Numbers in place of Dots if the Stack is greater than 10
# Use a larger font for the unicode dots
LAST=$(yabai -m query --windows --window stack.last | jq '.["stack-index"]')
if [[ $LAST -gt 10 ]]; then
sketchybar -m --set stack label.font="Iosevka Nerd Font:Bold:16.0" \
--set stack label=$(printf "[%s/%s]" "$CURRENT" "$LAST") \
--set stack_sep drawing=on \
--set stack drawing=on
exit 0
else
sketchybar -m --set stack label.font="Iosevka Nerd Font:Bold:22.0"
fi
# Create Stack Indicator
declare -a dots=()
for i in $(seq 0 $(expr $LAST - 1))
do
# Theme 1
# if [[ $i -lt $(expr $CURRENT - 1) ]]; then
# dots+="◖"
# elif [[ $i -gt $(expr $CURRENT - 1) ]]; then
# dots+="◗"
# elif [[ $i -eq $(expr $CURRENT - 1) ]]; then
# dots+="●"
# fi
# Theme 2
[[ $( expr $CURRENT - 1) -eq $i ]] && dots+="●" || dots+="○"
done
# Display Indicator
sketchybar -m --set stack label=$(printf "%s" ${dots[@]}) \
--set stack_sep drawing=on \
--set stack drawing=on |
Beta Was this translation helpful? Give feedback.
-
SKHD Modal IndicatorDESCRIPTION: Show the current SKHD Mode NOTES: You can hardcode the sketchybar commands into your skhdrc. I just use a seperate helper script to clean things up. sketchybarrc# M O D A L I N D I C A T O R
sketchybar -m --add item modal left
sketchybar -m --set modal icon=[N]
sketchybar -m --set modal icon_color =0xFF83A1F1 skhdrc# M O D E S
:: default : $HOME/.config/bin/helpers -n
:: window @ : $HOME/.config/bin/helpers -w
:: scripts @ : $HOME/.config/bin/helpers -s
# Mode Shortcuts
default, scripts < lcmd - escape ; window
window, scripts < escape ; default
default, window < lctrl - escape ; scripts helpersfunction normal_mode() {
echo "N O R M A L M O D E";
# C O L O R S
. $HOME/.cache/wal/colors.sh;
# Y A B A I
yabai -m config active_window_border_color 0xff${color5:1};
yabai -m config normal_window_border_color 0xff${color8:1};
yabai -m config insert_feedback_color 0xff${color5:1};
# S K E T C H Y B A R
sketchybar -m --bar color=0xF0${color0:1}
sketchybar -m --default label.color=0xFF${foreground:1}
sketchybar -m --default icon.color=0xFF${color5:1}
sketchybar -m --set modal icon.color=0xFF83A1F1
sketchybar -m --set modal icon="[N]"
}
# W I N D O W M O D E
function window_mode() {
echo "W I N D O W M O D E";
# C O L O R S
. $HOME/.cache/wal/colors.sh;
# Y A B A I
yabai -m config active_window_border_color 0xff${color3:1};
yabai -m config normal_window_border_color 0xff${color3:1};
yabai -m config insert_feedback_color 0xff${color3:1};
# S K E T C H Y B A R
sketchybar -m --bar color=0xF0${color3:1}
sketchybar -m --default label.color=0xFF${foreground:1}
sketchybar -m --default icon.color=0xFF${background:1}
sketchybar -m --set modal icon.color=0xFFA8CD76
sketchybar -m --set modal icon="[W]"
}
# S C R I P T S M O D E
function scripts_mode() {
echo "S C R I P T S M O D E";
# C O L O R S
. $HOME/.cache/wal/colors.sh;
# Y A B A I
yabai -m config active_window_border_color 0xff${color5:1};
yabai -m config normal_window_border_color 0xff${color5:1};
yabai -m config insert_feedback_color 0xff${color5:1};
# S K E T C H Y B A R
sketchybar -m --bar color=0xF0${color5:1}
sketchybar -m --default label.color=0xFF${foreground:1}
sketchybar -m --default icon.color=0xFF${color6:1}
sketchybar -m --set modal icon.color=0xFFF29B9B
sketchybar -m --set modal icon="[S]"
}
|
Beta Was this translation helpful? Give feedback.
-
yabai helperDESCRIPTION: shows the current yabai space, and the mode. Click the menu item to switch between the sketchybarrcsketchybar -m --add item yabai right
sketchybar -m --set yabai update_freq=3
sketchybar -m --set yabai script="~/.config/sketchybar/plugins/yabai.sh"
sketchybar -m --subscribe yabai space_change
sketchybar -m --set yabai click_script="~/.config/sketchybar/plugins/yabai_click.sh" yabai.sh#!/bin/bash
space_number=$(yabai -m query --spaces --display | jq 'map(select(."focused" == 1))[-1].index')
yabai_mode=$(yabai -m query --spaces --display | jq -r 'map(select(."focused" == 1))[-1].type')
sketchybar -m --set yabai label="$space_number:$yabai_mode" yabai_click.sh#!/bin/bash
space_number=$(yabai -m query --spaces --display | jq 'map(select(."focused" == 1))[-1].index')
yabai_mode=$(yabai -m query --spaces --display | jq -r 'map(select(."focused" == 1))[-1].type')
case "$yabai_mode" in
bsp)
yabai -m config layout stack
;;
stack)
yabai -m config layout float
;;
float)
yabai -m config layout bsp
;;
esac
new_yabai_mode=$(yabai -m query --spaces --display | jq -r 'map(select(."focused" == 1))[-1].type')
sketchybar -m --set yabai label="$space_number:$new_yabai_mode" |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Comprehensive Network Status IconDESCRIPTION: A simple network status icon that recognizes different network devices used for connection, as well as distinguishes between disconnected and off states for Wi-Fi. NOTES:
ISSUES:
plugins/net.sh#!/usr/bin/env sh
. "$CONFIG_DIR/resources.sh"
# When switching between devices, it's possible to get hit with multiple
# concurrent events, some of which may occur before `scutil` picks up the
# changes, resulting in race conditions.
sleep 1
services=$(networksetup -listnetworkserviceorder)
device=$(scutil --nwi | sed -n "s/.*Network interfaces: \([^,]*\).*/\1/p")
test -n "$device" && service=$(echo "$services" \
| sed -n "s/.*Hardware Port: \([^,]*\), Device: $device.*/\1/p")
color=$FG1
case $service in
"iPhone USB") icon=$NET_USB;;
"Thunderbolt Bridge") icon=$NET_THUNDERBOLT;;
Wi-Fi)
ssid=$(networksetup -getairportnetwork "$device" \
| sed -n "s/Current Wi-Fi Network: \(.*\)/\1/p")
case $ssid in
*iPhone*) icon=$NET_HOTSPOT;;
"") icon=$NET_DISCONNECTED; color=$FG2;;
*) icon=$NET_WIFI;;
esac;;
*)
wifi_device=$(echo "$services" \
| sed -n "s/.*Hardware Port: Wi-Fi, Device: \([^\)]*\).*/\1/p")
test -n "$wifi_device" && status=$( \
networksetup -getairportpower "$wifi_device" | awk '{print $NF}')
icon=$(test "$status" = On && echo "$NET_DISCONNECTED" || echo "$NET_OFF")
color=$FG2;;
esac
sketchybar --animate sin 5 --set "$NAME" icon="$icon" icon.color="$color" resources.sh#!/usr/bin/env sh
# From Gruvbox Dark
FG1=0xffebdbb2 # or whatever you use for active icons
FG2=0xff665c54 # or whatever you use for dim icons
# From SF Symbols
NET_WIFI= # Wi-Fi connected
NET_HOTSPOT= # iPhone Wi-Fi hotspot connected
NET_USB= # iPhone USB hotspot connected
NET_THUNDERBOLT= # Thunderbolt bridge connected
NET_DISCONNECTED= # Network disconnected, but Wi-Fi turned on
NET_OFF= # Network disconnected, Wi-Fi turned off sketchybarrc# ...
sketchybar --add item net right \
--set net script="$PLUGIN_DIR/net.sh" \
updates=on \
label.drawing=off \
--subscribe net wifi_change
# ... |
Beta Was this translation helpful? Give feedback.
-
Toggl Current Project and DescriptionDescription: Uses the Toggl API to query for the current running timer and puts it into your status bar. toggl.sh#!/usr/bin/env zsh
TOGGL_USERNAME=$(cat ~/.secrets/toggl/username.txt)
TOGGL_PASSWORD=$(cat ~/.secrets/toggl/password.txt)
read ENTRY_DESCRIPTION PROJECT_ID WORKSPACE_ID < <(echo $(curl -s https://api.track.toggl.com/api/v9/me/time_entries/current \
-H "Content-Type: application/json" \
-u $TOGGL_USERNAME:$TOGGL_PASSWORD | /jq -r '.description, .pid, .wid'))
if [ $ENTRY_DESCRIPTION = "null" ]; then
sketchybar --set toggl drawing=off updates=on
return
fi
PROJECT_NAME=$(curl -s https://api.track.toggl.com/api/v9/workspaces/$WORKSPACE_ID/projects/$PROJECT_ID \
-H "Content-Type: application/json" \
-u $TOGGL_USERNAME:$TOGGL_PASSWORD | jq -r '.name')
sketchybar --set toggl label="$PROJECT_NAME - $ENTRY_DESCRIPTION" drawing=on updates=on sketchybarrc
For the |
Beta Was this translation helpful? Give feedback.
-
Updated Window Title For Luasketchybar-lua-title.mp4The meat and bones of this are mostly the same as the first shell-based version that typkrft posted at the beginning of this thread, however there were a few changes that I made.
I found that if the window query command is ran when focused on a space without any windows, the command would return "could not retrieve window details.", without passing anything to sketchybar. Because of this the title would stay as the title of the last focused window, instead of reflecting that Finder was now focused. With the command ran through an external script, when no windows are present we will get an "empty" response back, so that the title can be set to "Finder" yabairc# S K E T C H Y B A R E V E N T S
yabai -m signal --add event=window_focused action="sketchybar --trigger window_focus &> /dev/null"
yabai -m signal --add event=window_title_changed action="sketchybar --trigger title_change &> /dev/null" query_window.shThis should be saved to a place that sketchybar can find. I have it saved in my `~/.scripts/` directory.#!/bin/sh
# Query yabai for window info
yabai_output=$(yabai -m query --windows --window)
# Check if the output is empty
if [ -z "$yabai_output" ]; then
# Output is empty, print "empty" to indicate no windows
echo "empty"
else
# Output is not empty, print the yabai output
echo "$yabai_output"
fi front_app.luaThe title is limited to 50 characters as before, and will be followed by ellipses if it is any longer. I also added the app icon with a short grow/shrink animation when it changes, like how it was with felix' old shell-based config. I've had to use sleep to give the first part of the animation enough time to complete, as if both animations were executed one after another they wouldn't do anything. Not too sure if that's working as intended or if it should be handled in a different manner.local colors = require("colors")
local settings = require("settings")
-- Events that get pushed by yabai
sbar.add("event", "window_focus")
sbar.add("event", "title_change")
local front_app = sbar.add("item", "front_app", {
position = "left",
display = "active",
icon = {
background = {
drawing = true,
image = {
border_width = 1,
border_color = colors.bg1,
}
},
},
label = {
font = {
style = settings.font.style_map["Black"],
size = 12.0,
},
},
updates = true,
})
local function set_window_title()
-- Offloading the "yabai -m query --windows --window" script to an external shell script so that we can determine whether the space has no windows
sbar.exec("~/.scripts/sketchybar/query_window.sh", function(result)
if result ~= "empty" and type(result) == "table" and result.title then
local window_title = result.title
if #window_title > 50 then
window_title = window_title:sub(1, 50) .. "..."
end
front_app:set({ label = { string = window_title } })
else
-- Set title to Finder, as empty spaces will not return a window title
front_app:set({ label = { string = "Finder" } })
end
end)
end
-- Animate app icon back to 1.0
local function end_bounce_animation()
sbar.animate("tanh", 15, function()
front_app:set({
icon = {
background = {
image = { scale = 1.0 },
}
}
})
end)
end
-- Make app icon slightly bigger before returning back to regular size
local function start_bounce_animation()
sbar.animate("tanh", 15, function()
front_app:set({
icon = {
background = {
image = { scale = 1.2 },
}
}
})
end)
-- Short delay so that full animation can occur
sbar.exec("sleep 0.25 && echo 'finishing bounce'", end_bounce_animation)
end
front_app:subscribe("front_app_switched", function(env)
front_app:set({
icon = { background = { image = "app." .. env.INFO } }
})
set_window_title()
start_bounce_animation()
end)
front_app:subscribe("space_change", function()
set_window_title()
start_bounce_animation()
end)
front_app:subscribe("window_focus", function()
set_window_title()
start_bounce_animation()
end)
front_app:subscribe("title_change", function()
set_window_title()
end)
front_app:subscribe("mouse.clicked", function(env)
sbar.trigger("swap_menus_and_spaces")
end) |
Beta Was this translation helpful? Give feedback.
-
wallpaper.movHere is a wallpaper selector that uses keybinds from skhd and yabai space swapping to set the wallpaper on spaces. The code might be inefficient so suggestions for this would be great. skhd/skhdrc
skhd/snippets/space_cycle_next.sh
skhd/snippets/space_cycle_prev.sh
wallpaper/init.lua
wallpaper/globals.lua
wallpaper/components.lua
wallpaper/helpers.lua
wallpaper/events.lua
settings.lua
colors.lua
|
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Media Info SliderThanks for the fantastic application, and for SbarLua! This is based on https://github.com/FelixKratz/SbarLua/blob/main/example/items/media.lua. On mouseover, it expands to display your playing media from whitelisted apps. Click toggles "Play/Pause". PreparationLaunch the If anyone has suggestions for a better way to implement "Play/Pause" please let me know! SbarLua moduleAdjust as needed with your colors, icons and fonts. local colors = require 'colors'
local app_icons = require 'app_icons'
local whitelist = {
['Spotify'] = true,
['Music'] = true,
['Podcasts'] = true,
['VLC'] = true,
['IINA'] = true,
['Arc'] = true
};
local media = sbar.add('item', 'media', {
icon = {
font = 'sketchybar-app-font:Regular:12.0',
color = colors.media,
},
label = {
font = 'IosevkaTerm Nerd Font:Regular:14.0',
width = 20,
padding_right = 12,
color = colors.media,
background = {
color = colors.inactive_bg,
corner_radius = 10,
height = 24,
}
},
position = 'center',
updates = true,
background = {
color = colors.inactive_bg,
corner_radius = 10,
height = 24,
},
width = 24,
})
local function animate_media_width(width)
sbar.animate('tanh', 30.0, function()
media:set({ label = { width = width } })
end)
end
media:subscribe('mouse.entered', function()
local text = media:query().label.value
animate_media_width(#text * 7) -- adjust depending on font width
end)
media:subscribe('mouse.exited', function()
animate_media_width(20)
end)
media:subscribe('mouse.clicked', function(env)
sbar.exec('shortcuts run "playpause"')
end)
media:subscribe('media_change', function(env)
if whitelist[env.INFO.app] then
local lookup = app_icons[env.INFO.app]
local icon = ((lookup == nil) and app_icons['default'] or lookup)
local playback_icon = ((env.INFO.state == 'playing') and '' or '')
local artist = (env.INFO.artist ~= "" and env.INFO.artist) or "Unknown Artist"
local title = (env.INFO.title ~= "" and env.INFO.title) or "Unknown Title"
local label = playback_icon .. ' ' .. artist .. ': ' .. title
sbar.animate('tanh', 10, function()
media:set({
icon = { string = icon },
label = label
})
end)
end
end) |
Beta Was this translation helpful? Give feedback.
-
Simple Sketchybar System Stats Event ProviderI was interested in learning Rust, so I decided to try my hand at creating a small Rust helper application to send trigger messages to Sketchybar to update system stats. https://github.com/joncrangle/sketchybar-system-stats It is a small CLI app that you can invoke from your Currently, the app can send trigger events for:
You can also specify a desired update interval (default 5 seconds) or bar name (if not using default). You can see all the options with This is my first ever Rust project, and it's been a good learning experience so far. If you're interested in trying it, you can clone and build it from source, or download the prebuilt binary for your Mac architecture. Example usage to create a disk_usage item: sketchybarrc## Start the helper with desired CLI args
killall stats_provider
# Update with path to stats_provider and invoke cli for your desired stats
# This example will send cpu, disk and ram usage percentages
$CONFIG_DIR/sketchybar-system-stats/target/release/stats_provider --cpu usage --disk usage --memory ram_usage &
sketchybar --add item disk_usage right \
--set disk_usage script="sketchybar --set disk_usage label=\$DISK_USAGE" \
--subscribe disk_usage system_stats disk_stats.lua-- Update with path to stats_provider
sbar.exec('killall stats_provider >/dev/null; $CONFIG_DIR/sketchybar-system-stats/target/release/stats_provider --cpu usage --disk usage --memory usage')
-- Subscribe and use the `DISK_USAGE` var
local disk_usage = sbar.add('item', 'disk_usage', {
position = 'right',
})
disk_usage:subscribe('system_stats', function(env)
disk_usage:set { label = env.DISK_USAGE }
end) You can create other items following the same pattern and style them to your heart's content. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Network upload and download speedCleanShot.2024-09-21.at.02.58.23.mp4Shows network upload and download speed, updates every 5 second with a background netstat.lualocal function formatBytes(bytes)
if bytes == 0 then
return "0b"
end
local k = 1024
local dm = 1
local sizes = { "b", "kb", "mb", "gb", "tb", "pb", "eb", "zb", "yb" }
local i = math.floor(math.log(bytes) / math.log(k))
local value = bytes / (k ^ i)
if value >= 100 then
dm = 0
end
local formattedValue = string.format("%." .. dm .. "f", value)
return formattedValue .. " " .. sizes[i + 1]
end
local colors = require("colors")
local netstat_up = sbar.add("item", {
position = "right",
width = 66,
icon = { drawing = false },
label = { color = colors.blue },
})
sbar.add("item", {
position = "right",
icon = {
string = "",
font = "JetBrainsMono Nerd Font:Regular:16.0",
color = colors.blue,
},
label = { drawing = false },
})
local netstat_down = sbar.add("item", {
position = "right",
width = 66,
icon = { drawing = false },
label = { color = colors.red },
})
sbar.add("item", {
position = "right",
icon = {
string = "",
font = "JetBrainsMono Nerd Font:Regular:16.0",
color = colors.red,
},
label = { drawing = false },
})
sbar.add("event", "netstat_update")
sbar.exec("~/.config/sketchybar/items/netstat.sh")
netstat_up:subscribe("netstat_update", function(env)
local download = formatBytes(env.DOWNLOAD)
local upload = formatBytes(env.UPLOAD)
netstat_up:set({
label = { string = upload },
})
netstat_down:set({
label = { string = download },
})
end)
~/.config/sketchybar/items/netstat.sh#!/usr/bin/env bash
pkill -f "netstat -w5"
netstat -w5 \
| awk '/[0-9]/ {print $3/5 "," $6/5; fflush(stdout)}' \
| xargs -I {} bash -c "sketchybar --trigger netstat_update DOWNLOAD=\$(cut -d, -f1 <<< {}) UPLOAD=\$(cut -d, -f2 <<< {})" &
|
Beta Was this translation helpful? Give feedback.
-
Upcoming Calendar Items Pop UpScreen.Recording.2024-09-26.at.12.29.19.AM.movIt currently displays today's and tomorrows events, it can be edited to add a larger range. I am sure this script can be improved so if anyone have any ideas please feel free to share. Cheers! calendar.sh#!/bin/bash
# === Configuration ===
ICS_URL= "https://your-calendar-url.com/calendar.ics"
ICS_FILE="calendar.ics"
source "$HOME/.config/sketchybar/colors.sh"
# === Download the ICS File ===
curl -s "$ICS_URL" -o "$ICS_FILE"
if [ $? -ne 0 ]; then
echo "Failed to download the ICS file."
exit 1
fi
# === Get Today's and Tomorrow's Dates in YYYYMMDD Format ===
TODAY=$(date +"%Y%m%d")
TOMORROW=$(date -v+1d +"%Y%m%d")
declare -a TODAY_EVENTS=()
declare -a TOMORROW_EVENTS=()
echo "Parsing events for today and tomorrow..."
EVENT_DATE=""
EVENT_SUMMARY=""
while IFS= read -r line; do
# Check for the start of an event
if [[ "$line" == "BEGIN:VEVENT" ]]; then
EVENT_DATE=""
EVENT_SUMMARY=""
elif [[ "$line" == DTSTART* ]]; then
# Extract date in YYYYMMDD format
if [[ "$line" =~ DTSTART[^:]*:([0-9]{8}) ]]; then
EVENT_DATE="${BASH_REMATCH[1]}"
elif [[ "$line" =~ DTSTART[^:]*:([0-9]{8})T ]]; then
EVENT_DATE="${BASH_REMATCH[1]}"
fi
elif [[ "$line" == SUMMARY* ]]; then
# Extract event summary
EVENT_SUMMARY="${line#SUMMARY:}"
elif [[ "$line" == "END:VEVENT" ]]; then
# Check if the event is today or tomorrow
if [[ "$EVENT_DATE" == "$TODAY" ]]; then
TODAY_EVENTS+=("$EVENT_SUMMARY")
fi
if [[ "$EVENT_DATE" == "$TOMORROW" ]]; then
# Combine summary and date
TOMORROW_EVENTS+=("$EVENT_SUMMARY")
fi
fi
done <"$ICS_FILE"
# sketchybar --set $NAME icon=" $(date '+%a %d. %b')" label="$(date '+%I:%M %p')"
sketchybar --set $NAME \
icon=" $(date '+%a %d. %b')" \
label="$(date '+%I:%M %p')" \
click_script="sketchybar --set $NAME popup.drawing=toggle"
if ((${#TODAY_EVENTS[@]})); then
sketchybar --add item calendar.date popup.$NAME \
--set calendar.date \
label.color=$WHITE \
label.font.size=14 \
label.align=left \
label="Today"
sketchybar --remove '/^calendar.event[0-9]+$/'
index=0
for today_event in "${TODAY_EVENTS[@]}"; do
index=$((index + 1))
echo $today_event
sketchybar --add item calendar.event${index} popup.$NAME \
--set calendar.event${index} \
label.color=$WHITE \
label.font="JetBrainsMono Nerd Font:Italic:12.0" \
label.max_chars=16 \
scroll_texts=on \
label.align=center \
label="$today_event"
done
fi
if ((${#TOMORROW_EVENTS[@]})); then
sketchybar --add item calendar.date2 popup.$NAME \
--set calendar.date2 \
label.color=$WHITE \
label.font.size=14 \
label.align=left \
label="$(date -v+1d '+%d. %b ')"
sketchybar --remove '/^calendar.$NAME[0-9]+$/'
index=0
for today_event in "${TOMORROW_EVENTS[@]}"; do
index=$((index + 1))
echo $today_event
sketchybar --add item calendar.tevent${index} popup.$NAME --set calendar.tevent${index} \
label.color=$WHITE \
label.font="JetBrainsMono Nerd Font:Italic:12.0" \
label.max_chars=16 \
scroll_texts=on \
label.align=center \
label="$today_event"
done
fi calendar_item.sh#!/bin/bash
sketchybar --add item calendar right \
--set calendar icon= \
update_freq=1 \
script=$PLUGIN_DIR/calendar.sh \
label="$(/bin/bash -c "date '+%a %d. %b %I:%M %p'")" \
background.height=25 \
click_script="sketchybar --set calendar popup.drawing=toggle" \
popup.drawing=off \
padding_left=0 \
padding_right=0 \
background.color=0xff232136
sketchybar --set calendar popup.background.border_width=2 \
popup.background.corner_radius=5 \
popup.background.border_color=$WHITE \
popup.background.color=$DARK_BG \
popup.height=0 |
Beta Was this translation helpful? Give feedback.
-
Aerospace Spaces/Apps!!!IMPORTANT!!! Aerospace v0.14.2-Beta don't have some bugfixes which are already included in the current main branch of aerospace which are mandatory to let the plugin work correctly! I used the yabai implementation from Felix as a base (https://github.com/FelixKratz/dotfiles/blob/master/.config/sketchybar/items/spaces.lua) so I named my aerospace workspaces with a number prefix (1_{workspace_name} .. n-th_{workspace_name}) because aerospace workspace query outputs them by alphanumeric ordering. I then strip the prefix inside the plugin and because the async behaviour of Don't forget to add the event trigger for workspace changes inside the
spaces.lualocal colors = require("colors")
local icons = require("icons")
local settings = require("settings")
local app_icons = require("helpers.app_icons")
local item_order = ""
sbar.exec("aerospace list-workspaces --all", function(spaces)
for space_name in spaces:gmatch("[^\r\n]+") do
local space = sbar.add("item", "space." .. space_name, {
icon = {
font = { family = settings.font.numbers },
string = string.sub(space_name, 3),
padding_left = 7,
padding_right = 3,
color = colors.white,
highlight_color = colors.red,
},
label = {
padding_right = 12,
color = colors.grey,
highlight_color = colors.white,
font = "sketchybar-app-font:Regular:16.0",
y_offset = -1,
},
padding_right = 1,
padding_left = 1,
background = {
color = colors.bg1,
border_width = 1,
height = 26,
border_color = colors.black,
}
})
local space_bracket = sbar.add("bracket", { space.name }, {
background = {
color = colors.transparent,
border_color = colors.bg2,
height = 28,
border_width = 2
}
})
-- Padding space
local space_padding = sbar.add("item", "space.padding." .. space_name, {
script = "",
width = settings.group_paddings,
})
space:subscribe("aerospace_workspace_change", function(env)
local selected = env.FOCUSED_WORKSPACE == space_name
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()
sbar.exec("aerospace workspace " .. space_name)
end)
space:subscribe("space_windows_change", function()
sbar.exec("aerospace list-windows --format %{app-name} --workspace " .. space_name, function(windows)
print(windows)
local no_app = true
local icon_line = ""
for app in windows:gmatch("[^\r\n]+") 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()
space:set({ label = icon_line })
end)
end)
end)
item_order = item_order .. " " .. space.name .. " " .. space_padding.name
end
sbar.exec("sketchybar --reorder apple " .. item_order .. " front_app")
end)
|
Beta Was this translation helpful? Give feedback.
-
1 - Hello, i search a widget in lua to show how many unread mail i have (i use mail official apps). |
Beta Was this translation helpful? Give feedback.
-
Icons based on kvndrsslr/sketchybar-app-font, but with consistent background ✨ |
Beta Was this translation helpful? Give feedback.
-
Connect/Disconnect GlobalProtectAn orange network icon that when is clicked when the GlobalProtect is switched on/off. --globalprotect.lua
local icons = require("icons")
local colors = require("colors")
local settings = require("settings")
local is_on = false
local globalprotect_icon = sbar.add("item", "widgets.globalprotect", {
position = "right",
padding_right = 0,
icon = {
string = icons.network,
width = 0,
align = "left",
color = colors.orange,
font = {
style = settings.font.style_map["Regular"],
size = 16.0
},
color = colors.orange
},
label = {
width = 30,
align = "left",
font = {
style = settings.font.style_map["Regular"],
size = 14.0
},
color = colors.orange
},
})
local globalprotect_bracket = sbar.add("bracket", "widgets.globalprotect.bracket", {
globalprotect_icon.name
}, {
background = { color = colors.bar_color,
border_color = colors.orange,
border_width = colors.border_width
},
popup = { align = "center" }
})
sbar.add("item", "widgets.globalprotect.padding", {
position = "right",
width = settings.group_paddings
})
local function runScript()
os.execute([[
osascript -e '
tell application "System Events" to tell process "GlobalProtect"
click menu bar item 1 of menu bar 2 -- Activates the GlobalProtect "window" in the menubar
set frontmost to true -- keep window 1 active
tell window 1
-- Click on the connect or disconnect button, depending on if they exist or not
if exists (first UI element whose title is "Connect") then
tell (first UI element whose title is "Connect") to if exists then click
else
tell (first UI element whose title is "Disconnect") to if exists then click
end if
end tell
click menu bar item 1 of menu bar 2 -- This will close the GlobalProtect "window" after clicking Connect/Disconnect. This is optional.
end tell
'
]])
end
local function switchOff()
runScript()
is_on = false
globalprotect_icon:set({
icon = { color = colors.orange },
background = { border_color = colors.orange }
})
globalprotect_bracket:set({
background = { border_color = colors.orange }
})
end
local function switchOn()
runScript()
is_on = true
globalprotect_icon:set({
icon = { color = colors.red }
})
globalprotect_bracket:set({
background = { border_color = colors.red }
})
end
local function toggleGlobalProtectConnection(env)
if is_on == true then
switchOff()
else
switchOn()
end
end
globalprotect_icon:subscribe("mouse.clicked", toggleGlobalProtectConnection) Credits to the creator of the osascript : https://gist.github.com/kaleksandrov/3cfee92845a403da995e7e44ba771183?permalink_comment_id=4416917#gistcomment-4416917 |
Beta Was this translation helpful? Give feedback.
-
Aerospace workspace application iconsThis plugin replace the items.spaces (used for showing mission control workspaces), instead this items.workspaces shows the aerospace workspaces. supports multiple monitors
exec-on-workspace-change = [
'/bin/bash', '-c', '/opt/homebrew/bin/sketchybar --trigger aerospace_workspace_change FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE'
]
local colors = require("colors")
local settings = require("settings")
local app_icons = require("helpers.app_icons")
local sbar = require("sketchybar")
sbar.add("event", "aerospace_workspace_change")
local workspaces = {}
-- Function to execute shell commands and return the output
local function execute_command(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
return result
end
local function add_workspace(monitor_id, workspace_id)
local space = sbar.add("space", "space." .. tostring(workspace_id), {
space = monitor_id,
display = monitor_id,
icon = {
font = { family = settings.font.numbers, size = 18 },
string = workspace_id,
padding_left = 15,
padding_right = 8,
color = colors.white,
highlight_color = colors.green,
},
label = {
padding_right = 20,
color = colors.grey,
highlight_color = colors.white,
font = "sketchybar-app-font:Regular:16.0",
y_offset = -1,
},
padding_right = 1,
padding_left = 1,
background = {
color = colors.bg1,
border_width = 1,
height = 26,
},
popup = { background = { border_width = 5, border_color = colors.black } },
})
workspaces[workspace_id] = 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,
height = 28,
border_width = 2,
},
})
-- Padding space
sbar.add("space", "space.padding." .. tostring(workspace_id), {
space = monitor_id,
script = "",
width = settings.group_paddings,
})
space:subscribe({ "aerospace_workspace_change" }, function(env)
local selected = tonumber(env.FOCUSED_WORKSPACE) == workspace_id
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.orange or colors.bg2 },
})
end)
end
-- Get monitor information
local monitors = {}
local monitor_output = execute_command("aerospace list-monitors")
for line in monitor_output:gmatch("[^\r\n]+") do
local id, name = line:match("(%d+) | (.+)")
if id and name then
monitors[tonumber(id)] = name
end
end
-- Get workspaces for each monitor
for monitor_id, _ in pairs(monitors) do
local workspace_output = execute_command("aerospace list-workspaces --monitor " .. monitor_id)
for workspace_id in workspace_output:gmatch("[^\r\n]+") do
add_workspace(monitor_id, tonumber(workspace_id))
end
end
local space_window_observer = sbar.add("item", {
drawing = false,
updates = true,
})
local function set_icon_line(workspace_id)
sbar.exec(
[[aerospace list-windows --workspace ]] .. tostring(workspace_id) .. [[ | awk -F '|' '{print $2}']],
function(appNames)
local appCounts = {}
-- Split the input string by newline into individual app names
for appName in string.gmatch(appNames, "[^\r\n]+") do
-- Trim leading and trailing whitespace
appName = appName:match("^%s*(.-)%s*$")
if appCounts[appName] then
appCounts[appName] = appCounts[appName] + 1
else
appCounts[appName] = 1
end
end
local icon_line = ""
local no_app = true
for app, _ in pairs(appCounts) 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
if workspace_id == "focused" then
sbar.exec("aerospace list-workspaces --focused", function(focused_workspace)
for id in focused_workspace:gmatch("%S+") do
workspaces[tonumber(id)]:set({ label = icon_line })
end
end)
else
sbar.animate("tanh", 10, function()
workspaces[tonumber(workspace_id)]:set({ label = icon_line })
end)
end
end
)
end
space_window_observer:subscribe({ "aerospace_workspace_change" }, function(env)
set_icon_line(env.FOCUSED_WORKSPACE)
end)
space_window_observer:subscribe({ "space_windows_change" }, function()
set_icon_line("focused")
end)
-- initial run
local ok, ws = pcall(function()
return execute_command("aerospace list-workspaces --focused"):gsub("%s+", "")
end)
local focused_workspace = ok and tonumber(ws) or -1
sbar.trigger("aerospace_workspace_change", { FOCUSED_WORKSPACE = focused_workspace }) |
Beta Was this translation helpful? Give feedback.
-
This is a thread to share the plugins you've created with the community.
Beta Was this translation helpful? Give feedback.
All reactions