diff options
| author | Robert Günzler <r@gnzler.io> | 2026-02-10 12:32:48 +0100 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2026-02-10 12:41:25 +0100 |
| commit | 63feeb9f369fc6176e85c1c2d8fcc863caad1946 (patch) | |
| tree | 41cd5d2d1ec36e74e464caab722cc9b460153f04 /.config/waybar | |
| parent | 5bd0a4aca65ecb9818ef1285982d160b6b6ff665 (diff) | |
start new
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to '.config/waybar')
| -rw-r--r-- | .config/waybar/config.jsonc | 257 | ||||
| -rwxr-xr-x | .config/waybar/modules/covid.sh | 85 | ||||
| -rwxr-xr-x | .config/waybar/modules/gamma.go | 78 | ||||
| -rw-r--r-- | .config/waybar/modules/go.mod | 5 | ||||
| -rw-r--r-- | .config/waybar/modules/go.sum | 4 | ||||
| -rwxr-xr-x | .config/waybar/modules/hotspots.sh | 21 | ||||
| -rwxr-xr-x | .config/waybar/modules/mediaplayer.py | 171 | ||||
| -rw-r--r-- | .config/waybar/modules/mpris.awk | 54 | ||||
| -rwxr-xr-x | .config/waybar/modules/mpris.sh | 6 | ||||
| -rwxr-xr-x | .config/waybar/modules/timetracked.sh | 23 | ||||
| -rwxr-xr-x | .config/waybar/modules/todo.go | 229 | ||||
| -rwxr-xr-x | .config/waybar/modules/toggl.lua | 28 | ||||
| -rwxr-xr-x | .config/waybar/modules/vpn.sh | 24 | ||||
| -rwxr-xr-x | .config/waybar/modules/weather.sh | 42 | ||||
| -rw-r--r-- | .config/waybar/style.css | 390 |
15 files changed, 0 insertions, 1417 deletions
diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc deleted file mode 100644 index 70ab60f..0000000 --- a/.config/waybar/config.jsonc +++ /dev/null @@ -1,257 +0,0 @@ -{ - "modules-left": ["sway/mode", "sway/workspaces", "mpris"], - - "sway/workspaces": { - "format": "{icon}", - "format-icons": { - "1": "", - "2": "", - "3": "", - "m": "", - "v": "", - "g": "", - "__vnc": "" - } - }, - - "river/tags": { - "format": ":{}", - "num-tags": 9 - }, - - "mpris": { - "max-width": 60, - "format": "{player_icon} {dynamic}", - "format-paused": "{status_icon} <i>{dynamic}</i>", - "player-icons": { - "default": "", - // "firefox": "X", - // "mpv": "XX", - }, - "status-icons": { - "paused": "", - "playing": "", - "stopped": "", - } - }, - - // ------------------------------------------------------------------------ // - - "modules-center": ["custom/weather", "clock#local", "clock#utc", "clock#extra", "custom/timetracked", "custom/hotspots"], - - "custom/weather": { - "format": "{icon} {percentage}℃", - "format-icons": { - "sunny": "", - "partlycloudy": "", - "cloudy": "", - "verycloudy": "", - "fog": "", - "lightrain": "", - "heavyrain": "", - "hail": "", - "thunder": "", - "lightsnow": "", - "heavysnow": "", - "snowrain": "" - }, - "exec": "$HOME/.config/waybar/modules/weather.sh", - "interval": 600, - "return-type": "json", - "tooltip": true, - "on-click": "swx -t env REPORT=1 $HOME/.config/waybar/modules/weather.sh" - }, - - "clock#local": { - "format": "{:<i>%a</i> %d %b <b>%H:%M</b>}", - "tooltip-format": "TZ: {:%Z %z}\n\n{calendar}", - // "locale": "ja_JP.utf-8" - // "locale": "en_US.utf-8" - }, - - "clock#utc": { - "timezone": "UTC", - "format": "{:<small>%Z</small> %H:%M}", - "tooltip-format": "{:%Z %z}" - }, - "clock#extra": { - "timezone": "Asia/Kolkata", - "format": "{:<small>%Z</small> %H:%M}", - "tooltip-format": "{:%Z %z}" - }, - - "custom/todo": { - "format": "{icon} {}", - "format-icons": { - "off": "", - "on": "" - }, - "exec": "env WAYBAR_TODO_FILE=$HOME/.zk/todo.md $HOME/.config/waybar/modules/waybar-todo", - "on-click": "pkill -x -USR1 waybar-todo", - "on-click-right": "pkill -x -USR2 waybar-todo", - "escape": true, - "return-type": "json" - }, - - "custom/timetracked": { - "format": "{}", - "exec": "$HOME/.config/waybar/modules/timetracked.sh", - "on-click": "$HOME/.config/waybar/modules/timetracked.sh on-click", - "escape": true, - "return-type": "json" - }, - - "custom/hotspots": { - "format": "{}", - "exec": "$HOME/.config/waybar/modules/hotspots.sh", - "on-click": "$HOME/.config/waybar/modules/hotspots.sh click", - "escape": true, - "interval": 600, - "return-type": "json" - }, - - // ------------------------------------------------------------------------ // - "modules-right": ["tray", "cpu", "memory", "disk#root", "disk#home", "temperature", "idle_inhibitor", "backlight", "pulseaudio", "custom/vpn", "network#tailscale", "network", "battery"], - - "tray": { - "icon-size": 15, - "spacing": 5 - }, - - "custom/covid": { - "format": "{icon} {}", - "format-icons": { - "": "x", - "gray": "", - "green": "", - "yellow": "", - "orange": "", - "red": "", - "darkred": "", - "darkdarkred": "" - }, - "exec": "$HOME/.config/waybar/modules/covid.sh", - "interval": 86400, - "return-type": "json" - }, - - "disk#root": { - "path": "/", - "format": " <small>/ </small>{percentage_used}%" - }, - - "disk#home": { - "path": "/home", - "format": "<small>/home </small>{percentage_used}%" - }, - - "cpu": { - "format": "{icon} {usage}%", - "format-icons": ["", ""], - "on-click": "$HOME/bin/swx -t -- btop" - }, - - "memory": { - "format": "{icon} {percentage}%", - "format-icons": ["", ""], // - "on-click": "$HOME/bin/swx -t -- btop" - }, - - "temperature": { - "critical-threshold": 100, - "format": "{icon} {temperatureC}℃", - "format-icons": ["", "", "", ""] - }, - - "idle_inhibitor": { - "format": "{icon}", - "format-icons": { - "activated": "", - "deactivated": "" - } - }, - - "backlight": { - "device": "auto", - "format": "{icon}", - "format-icons": ["", "", "", ""], - "on-scroll-down": "light -A 5", - "on-scroll-up": "light -U 5", - // save current level - // then set to minimum brightness - "on-click-right": "light -O; light -S $(light -P)", - // revert to previously saved brightness - "on-click-middle": "light -I" - }, - - "custom/gamma": { - "format": "{icon}", - "format-icons": { - "dawn": "", - "day": "", - "dusk": "", - "night": "", - }, - "exec": "env GAMMA_COMMAND='wlsunset -l $HOME_LAT -L $HOME_LON -p' YAEGI_SYSCALL=1 YAEGI_UNRESTRICTED=1 ${HOME}/.config/waybar/modules/gamma.go", - "return-type": "json" - }, - - "pulseaudio": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} {volume}%", - "format-muted": " {volume}%", - "format-icons": { - "easyeffects_sink": "", - "headphones": "", - "handsfree": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click-right": "soundswitch -m", - "on-click-middle": "swx easyeffects", - "on-click": "swx -t -F '0.4' pulsemixer" - }, - - "custom/vpn": { - "exec": "${HOME}/.config/waybar/modules/vpn.sh", - "interval": 600, - "return-type": "json", - "on-click": "${HOME}/.config/waybar/modules/vpn.sh toggle", - }, - - "network#tailscale": { - "interface": "tailscale0", - "format": "", - "format-disconnected": "", - "tooltip-format": "{ifname}: {bandwidthUpBits} {bandwidthDownBits}", - "tooltip-format-disconnected": "disconnected", - "on-click": "${HOME}/.config/waybar/modules/tailscale.sh toggle", - }, - - "network": { - "format-wifi": "{icon} {signalStrength}%", - "format-icons": ["", "", "", "", ""], - "format-ethernet": "", - "format-linked": " {ifname}", - "format-disconnected": " ", - "tooltip-format": "{ifname}: {ipaddr}/{cidr}\ngateway: {gwaddr}\nssid: {essid}\nsignal: {signaldBm} dbm\ndown: {bandwidthDownBits}\nup: {bandwidthUpBits}", - "tooltip-format-disconnected": "disconnected", - // cycles through wifi/ethernet/off - // "on-click": "${HOME}/.config/waybar/modules/network.sh toggle", - }, - - "battery": { - "states": { - "good": 90, - "warning": 30, - "critical": 15 - }, - "format": "{icon} {capacity}%", - "format-charging": " {capacity}%", - "format-full-charging": "", - "format-icons": ["", "", "", ""] - }, -} diff --git a/.config/waybar/modules/covid.sh b/.config/waybar/modules/covid.sh deleted file mode 100755 index 46727d7..0000000 --- a/.config/waybar/modules/covid.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh - -set -e -[ -n "$DEBUG" ] && { - set -x - curl_args='-v' -} - -# check requirements -for tool in awk curl jq flock; do - if ! command -v "$tool" >/dev/null; then - printf "%s: %s not installed but required\n" "$(basename "$0")" "$tool" >&2 - exit 1 - fi -done - -# incidence = (sumCasesLast7Days / EWZ) * 100000 -lat=${HOME_LAT:?} -lon=${HOME_LON:?} -# fields='GEN,RS,EWZ,EWZ_BL,BL_ID,cases,cases_per_100k,cases7_per_100k,cases7_bl_per_100k,last_update,BL,IBZ' -fields='GEN,cases7_bl_per_100k' -# see https://experience.arcgis.com/experience/478220a4c454480e823b17327b2bf1d4 -uri="https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=${fields}&geometry=${lon}%2C${lat}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelWithin&returnGeometry=false&outSR=4326&f=json" - -_data=$(curl -sSL -H 'Accept: application/json' ${curl_args} "${uri}" | jq -r '.features[0].attributes') -if [ "${_data}" = "null" ]; then - printf "{}\n" - exit 0 -fi - -historical_data=${HOME}/covid-history.csv -loc=$(printf "%s" "${_data}" | jq -r '.GEN') -last_update=$(printf "%s" "${_data}" | jq -r '.last_update') -# printf "${_data}" | jq -r '.' -incidence_f=$(printf "%.1f" "$(printf "%s" "${_data}" | jq -r '.cases7_bl_per_100k')") -incidence_i=$(printf "%.0f" "${incidence_f}") - -# store -if [ -n "${last_update}" ] && [ -n "${incidence_f}" ]; then - tmp_HISTFILE=$(mktemp -u --tmpdir waybar-module-covid.XXXXX) - ( - cat "${historical_data}" - ts=$(printf "%s" "${last_update}" | cut -d',' -f1 | tr '.' '-') - printf "%s,%s\n" "${ts}" "${incidence_f}" - ) | uniq | tee "${tmp_HISTFILE}" >/dev/null - flock -x "${historical_data}" mv "${tmp_HISTFILE}" "${historical_data}" -fi - -mxy=$(tail -n 7 "${historical_data}" | awk -F',' '{y=y+$2} END{print ((NR*(NR+1))/2)/NR, y/NR}') -trend=$(awk -F',' --assign="mx=$(printf "%s" "$mxy" | cut -d' ' -f1)" --assign="my=$(printf "%s" "$mxy" | cut -d' ' -f2)" '{up= up+(NR-mx)*($2-my); down= down+(NR-mx)**2} END{if(down==0){print 0}else{print up/down};}' "${historical_data}") -trend_arrow="" -[ "$(printf "%.0f" "${trend}")" -gt 0 ] && trend_arrow="" -[ "$(printf "%.0f" "${trend}")" -lt 0 ] && trend_arrow="" - -color='green' -if [ "${incidence_i}" -eq "0" ]; then - color='gray' -fi -if [ "${incidence_i}" -gt "1" ]; then - color='green' -fi -if [ "${incidence_i}" -gt "25" ]; then - color='yellow' -fi -if [ "${incidence_i}" -gt "35" ]; then - color='orange' -fi -if [ "${incidence_i}" -gt "50" ]; then - color='red' -fi -if [ "${incidence_i}" -gt "100" ]; then - color='darkred' -fi -if [ "${incidence_i}" -gt "250" ]; then - color='darkdarkred' -fi - -tooltip="7 Tage Inzidenz für ${loc} -last update: ${last_update} - -history (${trend_arrow}): -$(awk -F, '{print $1 " " $2}' "${historical_data}" | tail -n10 | tac)" - -jq -nr \ - "{ text: \"${trend_arrow}${incidence_f}\", percentage: \"${incidence_i}\", class: \"${color}\", alt: \"${color}\", tooltip: \"${tooltip}\" } | @text" diff --git a/.config/waybar/modules/gamma.go b/.config/waybar/modules/gamma.go deleted file mode 100755 index 9813cc8..0000000 --- a/.config/waybar/modules/gamma.go +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env yaegi - -package main - -import ( - "encoding/json" - "log" - "os" - "os/exec" - "os/signal" - "runtime" - "strings" - . "syscall" -) - -func main() { - runtime.GOMAXPROCS(1) - - var ( - update = make(chan os.Signal, 1) - cancel = make(chan os.Signal, 1) - ) - signal.Notify(update, SIGUSR1, SIGUSR2, SIGHUP) - signal.Notify(cancel, SIGTERM, SIGINT) - - // could use golang.org/x/sys/unix.Prctl here - // but I want to avoid the dependency - if _, _, e := Syscall6(uintptr(SYS_PRCTL), - uintptr(PR_SET_PDEATHSIG), - uintptr(SIGTERM), - 0, 0, 0, 0); e != 0 { - log.Fatalf("error: %v", e) - } - - lookup() - for { - select { - case sig := <-update: - switch sig { - case SIGUSR1: - printJson("day") - // TODO(robert): toggle wlsunset off? - case SIGUSR2: - printJson("night") - // TODO(robert): toggle wlsunset on? - case SIGHUP: - lookup() - } - case <-cancel: - log.Printf("%v exiting\n", os.Args[0]) - os.Exit(0) - } - } -} - -func printJson(phase string) { - _ = json.NewEncoder(os.Stdout).Encode(map[string]interface{}{ - "class": phase, - "alt": phase, - "tooltip": "gamma: " + phase, - "text": phase, - }) -} - -func lookup() { - cmdEnv, ok := os.LookupEnv("GAMMA_COMMAND") - if !ok { - printJson("unknown") - return - } - b, err := exec.Command("bash", "-c", cmdEnv).Output() - if err != nil { - log.Fatalf("error: %v", err) - return - } - phase := strings.TrimSpace(string(b)) - printJson(phase) -} diff --git a/.config/waybar/modules/go.mod b/.config/waybar/modules/go.mod deleted file mode 100644 index fdeae95..0000000 --- a/.config/waybar/modules/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module git.sr.ht/~robertgzr/dotfiles/.config/waybar/modules - -go 1.15 - -require github.com/fsnotify/fsnotify v1.4.9 // indirect diff --git a/.config/waybar/modules/go.sum b/.config/waybar/modules/go.sum deleted file mode 100644 index b12c1ed..0000000 --- a/.config/waybar/modules/go.sum +++ /dev/null @@ -1,4 +0,0 @@ -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/.config/waybar/modules/hotspots.sh b/.config/waybar/modules/hotspots.sh deleted file mode 100755 index fe2ff65..0000000 --- a/.config/waybar/modules/hotspots.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -set -e - -case "$1" in -click) - uri=$(hspl -u) - xdg-open "http://$uri" - ;; -*) - output=$(hspl || echo "none") - if [ "$output" != "none" ]; then - jq -nc \ - --arg text " $(head -n1 <<<"$output")" \ - --arg tooltip "$(tail -n+2 <<<"$output")" \ - --arg class "$(if [ "$(hspl -d)" -lt 100 ]; then echo "soon"; else echo ""; fi)" \ - '{text:$text,tooltip:$tooltip,class:$class}' - else - jq -nc '{}' - fi - ;; -esac diff --git a/.config/waybar/modules/mediaplayer.py b/.config/waybar/modules/mediaplayer.py deleted file mode 100755 index 8082825..0000000 --- a/.config/waybar/modules/mediaplayer.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import json -import logging -import signal -import sys -from datetime import timedelta -from math import floor -import prctl - -# yapf: disable -import gi -gi.require_version('Playerctl', '2.0') -from gi.repository import GLib, Playerctl -# yapf: enable - -logger = logging.getLogger(__name__) -loop = GLib.MainLoop() - -def write_output(text, player): - logger.info('Writing output') - - output = { - 'text': text, - 'class': player.props.player_name, - 'alt': player.props.player_name - } - sys.stdout.write(json.dumps(output) + '\n') - sys.stdout.flush() - - -def on_play(player, status, manager): - logger.info('Received new playback status') - on_metadata(player, player.props.metadata, manager) - - -def on_metadata(player, metadata, manager): - logger.info('Received new metadata') - track_info = '' - - if player.props.player_name == 'spotify' and \ - 'mpris:trackid' in metadata.keys() and \ - ':ad:' in player.props.metadata['mpris:trackid']: - track_info = 'AD PLAYING' - - if player.get_title() and player.get_title() != '': - track_info = f"{player.get_title()}" - if player.get_artist() and player.get_artist() != '': - track_info = f"{player.get_artist()} - {track_info}" - - if 'mpris:length' in player.props.metadata.keys(): - dur_td = timedelta(microseconds=player.props.metadata['mpris:length']) - dur_h, remainder = divmod(dur_td.total_seconds(), 3600) - dur_m, dur_s = divmod(remainder, 60) - dur = f"{floor(dur_m)}:{floor(dur_s):02}" - if dur_h > 0: - dur = f"{floor(dur_h)}:{dur}" - track_info = '{} ({})'.format(track_info, str(dur)) - - if player.props.status == 'Paused' and track_info: - track_info = '<i>'+track_info+'</i>' - - if player.props.status == 'Stopped': - return - - if track_info == '': - logger.warning('TrackInfo was empty after parsing') - return - - write_output(track_info, player) - - -def on_player_appeared(manager, player, selected_player=None, ignored_players=None): - if player is not None \ - and (selected_player is None or player.name == selected_player) \ - and not (player.name in ignored_players): - init_player(manager, player) - else: - logger.debug( - "New player appeared, but it's not the selected player, skipping") - - -def on_player_vanished(manager, player): - logger.info('Player has vanished') - sys.stdout.write('\n') - sys.stdout.flush() - - -def init_player(manager, name): - logger.debug('Initialize player: {player}'.format(player=name.name)) - player = Playerctl.Player.new_from_name(name) - player.connect('playback-status', on_play, manager) - player.connect('metadata', on_metadata, manager) - manager.manage_player(player) - on_metadata(player, player.props.metadata, manager) - - -def signal_handler(sig, frame): - logger.warning('Received signal to stop, exiting') - sys.stdout.write('\n') - sys.stdout.flush() - loop.quit() - sys.exit(0) - - -def parse_arguments(): - parser = argparse.ArgumentParser() - - # Increase verbosity with every occurance of -v - parser.add_argument('-v', '--verbose', action='count', default=0) - - # Define for which player we're listening - parser.add_argument('--player', - help='player to listen for') - - # Define which players to ignore entirely - parser.add_argument('-I', '--ignore', - action='append', - help='players to ignore') - - return parser.parse_args() - - -def main(): - arguments = parse_arguments() - - # Initialize logging - logging.basicConfig(stream=sys.stderr, - level=logging.DEBUG, - format='%(name)s %(levelname)s %(message)s') - - # Logging is set by default to WARN and higher. - # With every occurrence of -v it's lowered by one - logger.setLevel(max((3 - arguments.verbose) * 10, 0)) - - # Log the sent command line arguments - logger.debug('Arguments received {}'.format(vars(arguments))) - - manager = Playerctl.PlayerManager() - manager.connect('name-appeared', - lambda *args: on_player_appeared(*args, arguments.player, arguments.ignore)) - manager.connect('player-vanished', on_player_vanished) - - # set the process up to die when the parent exits - prctl.set_pdeathsig(signal.SIGTERM) - - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGHUP, signal_handler) - - for player in manager.props.player_names: - if arguments.player is not None and arguments.player != player.name: - logger.debug( - '{player} is not the filtered player, skipping it'.format( - player=player.name)) - continue - - if arguments.ignore is not None and player.name in arguments.ignore: - logger.debug( - '{player} is ignored, skipping it'.format( - player=player.name)) - continue - - init_player(manager, player) - - loop.run() - - -if __name__ == '__main__': - main() diff --git a/.config/waybar/modules/mpris.awk b/.config/waybar/modules/mpris.awk deleted file mode 100644 index 194aa73..0000000 --- a/.config/waybar/modules/mpris.awk +++ /dev/null @@ -1,54 +0,0 @@ -{ - gsub(/"/,"") - gsub(/'/,"\047") - # print "DEBUG: " $0 - - artist=$1 - album=$2 - title=$3 - position=$4 - player=$5 - status=$6 -} - -($0 == "") || (status ~ /stopped/) { - system("jq -Mnc {}") - next -} - -(status ~ /playing/) { - icon="" -} -(status ~ /paused/) { - icon="" -} -(artist != "") && (album != "") { - text=sprintf("%s - %s - %s (%s)", artist, album, title, position) - tooltip=sprintf("%s\nby %s\nfrom %s\n(%s)", title, artist, album, player) -} -(artist == "") { - text=sprintf("%s - %s (%s)", album, title, position) - tooltip=sprintf("%s\nfrom %s\n(%s)", title, album, player) -} -(album == "") { - text=sprintf("%s - %s (%s)", artist, title, position) - tooltip=sprintf("%s\nby %s\n(%s)", title, artist, player) -} -(artist == "") && (album == "") { - text=sprintf("%s (%s)", title, position) - tooltip=sprintf("%s\n(%s)", title, player) -} -# edge cases to beautify the output -(player == "tdesktop") && (title ~ /Unknown Track/) { - text="telegram voice message" -} - -{ - system(sprintf("jq -rMnc --arg class \"%s\" --arg text \"%s %s\" --arg tt \"%s\" '{ class: $class, text: $text|@html, tooltip: $tt|@html }'", \ - status, - icon, - text, - tooltip)) -} - -END {} diff --git a/.config/waybar/modules/mpris.sh b/.config/waybar/modules/mpris.sh deleted file mode 100755 index 5f5d5c6..0000000 --- a/.config/waybar/modules/mpris.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -e -[ -n "$DEBUG" ] && set -x - -playerctl -sF metadata -f '"{{artist}}","{{album}}","{{title}}","{{duration(position)}}","{{playerName}}","{{lc(status)}}"' | awk -F',' -f "${HOME}/.config/waybar/modules/mpris.awk" diff --git a/.config/waybar/modules/timetracked.sh b/.config/waybar/modules/timetracked.sh deleted file mode 100755 index 4e384bf..0000000 --- a/.config/waybar/modules/timetracked.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -e -[ -n "$DEBUG" ] && set -x - -if ! command -v timetrace >/dev/null 2>&1; then - exit 0 -fi - -case "$1" in -on-click) - timetrace status >/dev/null && timetrace stop - exit 0 - ;; - -*) ;; -esac - -while true; do - timetrace status -o json | - jq -c 'if .project == "---" then {} else { text: (["▶", .trackedTimeToday] | join(" ")), class: "timetracked", alt: "timetracked" } end' 2>/dev/null - sleep 30 -done diff --git a/.config/waybar/modules/todo.go b/.config/waybar/modules/todo.go deleted file mode 100755 index 2692ec9..0000000 --- a/.config/waybar/modules/todo.go +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env yaegi - -// # Documentation -// we try to read a file pointed to by WAYBAR_TODO_FILE. -// While no particular format is assumed, we recommend -// Markdown. -// We extract the todos from the top-level list items -// (listings start with a `*` character). -// -// # Usage: -// go build -o waybar-todo todo.go -package main - -import ( - "bufio" - "encoding/json" - "log" - "os" - "os/signal" - "regexp" - "runtime" - "strings" - "time" - - "github.com/fsnotify/fsnotify" - "golang.org/x/sys/unix" -) - -const ( - TODO_INACTIVE_STRING string = "" - TODO_LABEL_REGEX string = `\[\[!(.*)\]\]` -) - -var ( - active = true - todofile = os.Getenv("WAYBAR_TODO_FILE") - cookiefile = os.ExpandEnv("${XDG_RUNTIME_DIR}/waybar-todo.cookie") - labelFilter = os.Getenv("WAYBAR_TODO_FILTER") -) - -func printJson(text, tooltip string, class []string, alt string, percentage int) error { - return json.NewEncoder(os.Stdout).Encode(map[string]interface{}{ - "text": text, - "tooltip": tooltip, - "class": class, - "alt": alt, - "percentage": percentage, - }) -} - -type todoItem struct { - text string - label string -} - -func readTodofile2(path string) ([]todoItem, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - var todos []todoItem - for lr := bufio.NewScanner(f); lr.Scan(); { - skip := 0 - switch { - case strings.HasPrefix(lr.Text(), "*"): - skip = 2 - case strings.HasPrefix(lr.Text(), "- [ ]"): - skip = 6 - case strings.HasPrefix(lr.Text(), "- [x]"): - fallthrough - default: - continue - } - ti := todoItem{text: lr.Text()[skip:]} - matches := labelre.FindAllStringSubmatch(ti.text, -1) - if matches != nil && len(matches) > 0 { - ti.label = matches[0][1] - ti.text = strings.TrimSpace( - strings.Replace(ti.text, matches[0][0], "", 1)) - } - todos = append(todos, ti) - } - return todos, nil -} - -func setCookie(active bool) error { - if !active { - _, err := os.Create(cookiefile) - return err - } - return os.Remove(cookiefile) -} - -func update() error { - if _, err := os.Stat(cookiefile); err == nil { - log.Printf("cookie set, we're inactive") - active = false - } - if !active { - return printJson(TODO_INACTIVE_STRING, "* inactive *", []string{"off"}, "off", 0) - } - todos, err := readTodofile2(todofile) - if err != nil { - return err - } - var ( - text string - tooltip []string - extraClass string - ) - for _, item := range todos { - if labelFilter != "" && strings.Contains(labelFilter, item.label) { - continue - } - if text == "" { - text = item.text - extraClass = item.label - continue - } - // render out the rest of the todos into the tooltip - tooltip = append(tooltip, item.text) - } - return printJson(text, strings.Join(tooltip, "\n"), []string{"on", extraClass}, "on", 1) -} - -var labelre *regexp.Regexp - -func init() { - labelre = regexp.MustCompile(TODO_LABEL_REGEX) -} - -func main() { - runtime.GOMAXPROCS(1) - - var ( - updateC = make(chan os.Signal, 1) - cancelC = make(chan os.Signal, 1) - ) - signal.Notify(updateC, unix.SIGUSR1, unix.SIGUSR2, unix.SIGHUP) - signal.Notify(cancelC, unix.SIGTERM, unix.SIGINT) - - var err error - // we will receive a SIGTERM if our parent dies - err = unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGTERM), 0, 0, 0) - if err != nil { - log.Fatalf("error: setting prctl: %v", err) - } - - if todofile == "" { - panic("missing TODO file") - // // get from nb(1) - // nb := exec.Command("sh", "-c", "nb show --no-color --path todo") - // nb_output, err := nb.Output() - // if err != nil { - // e := err.(*exec.ExitError) - // log.Fatalf("error: finding todofile via nb: %s", e.Stderr) - // } - // todofile = strings.TrimSpace(string(nb_output)) - } - - log.Printf("watching %q", todofile) - - w, err := fsnotify.NewWatcher() - if err != nil { - log.Fatalf("error: creating watcher: %v", err) - } - defer w.Close() - - if err := w.Add(todofile); err != nil { - log.Fatalf("error: adding watch: %v", err) - } - - if err := update(); err != nil { - // fail here because it's the first time we - // try to read the todofile. - log.Fatalf("error: %v", err) - } - for { - select { - case evt, ok := <-w.Events: - if !ok { - return - } - // see https://github.com/fsnotify/fsnotify/issues/94 - // https://github.com/gohugoio/hugo/pull/4720 - if evt.Op&fsnotify.Remove == fsnotify.Remove { - counter := 0 - for w.Add(todofile) != nil { - counter++ - if counter >= 1000 { - log.Panic("error: unable to add file watcher") - } - time.Sleep(100 * time.Millisecond) - } - } - goto force_update - case err, ok := <-w.Errors: - if !ok { - return - } - log.Printf("error: from watcher: %v", err) - - case sig := <-updateC: - switch sig { - case unix.SIGUSR1: // on - active = !active - if err := setCookie(active); err != nil { - log.Printf("err: %v", err) - } - goto force_update - case unix.SIGUSR2: // - if strings.Contains(labelFilter, "work") { - labelFilter = strings.Trim(strings.ReplaceAll(labelFilter, "work", ""), ",") - } else { - labelFilter = strings.Join([]string{labelFilter, "work"}, ",") - } - continue - case unix.SIGHUP: // force update - log.Println("force update") - goto force_update - } - case <-cancelC: - log.Printf("%s exiting", os.Args[0]) - os.Exit(0) - } - force_update: - _ = update() - } -} diff --git a/.config/waybar/modules/toggl.lua b/.config/waybar/modules/toggl.lua deleted file mode 100755 index 7c9f0b9..0000000 --- a/.config/waybar/modules/toggl.lua +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env luajit - -TOKEN = os.getenv("TOGGL_TOKEN") -if not TOKEN then - io.stderr:write("need TOGGL_TOKEN\n") - os.exit(1) -end - -function timer_duration() - cmd = string.format('toggl -t %s -j timer ls | jq -r ".[0].duration"', TOKEN) - local f = assert(io.popen(cmd, 'r')) - local s = assert(f:read('*a')) - f:close() - if not (s == '') then - return tonumber(s) - end -end - -unix_time = os.time() - -diff = timer_duration() -if not diff then - os.exit(0) -end - -d = unix_time + diff - -print(string.format('%dh %.2dm', d/(60*60), d/60%60)) diff --git a/.config/waybar/modules/vpn.sh b/.config/waybar/modules/vpn.sh deleted file mode 100755 index c4d50fa..0000000 --- a/.config/waybar/modules/vpn.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -set -e -[ -n "$DEBUG" ] && set -x - -case "$1" in -toggle) exit 1 ;; -esac - -extern_ip=$(curl -SsfL http://api.ipify.org/?format=text) - -vpn_is_up() { - case "$extern_ip" in - 138.201.245.159) return 0 ;; # hetzner node - esac - return 1 -} - -if vpn_is_up; then - printf '{"text": "", "tooltip": "external ip is %s"}\n' "$extern_ip" -else - # printf '{"text": "", "tooltip": "disconnected"}\n' - printf '{}\n' -fi diff --git a/.config/waybar/modules/weather.sh b/.config/waybar/modules/weather.sh deleted file mode 100755 index 929732b..0000000 --- a/.config/waybar/modules/weather.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -set -e -[ -n "$DEBUG" ] && set -x - -loc=$1 -if [ -z "${loc}" ]; then - # use /etc/localtime - # loc=$(basename "$(readlink -f /etc/localtime)") - loc="${HOME_LAT},${HOME_LON}" -fi - -if [ -n "$REPORT" ]; then - curl -s v2.wttr.in/"${loc}"?F | less - exit 0 -fi - -data="$(curl -s wttr.in/"${loc}"?format=j1)" - -class= -case "$(echo "${data}" | jq -r '.current_condition[].weatherCode')" in -113) class="sunny" ;; -116) class="partlycloudy" ;; -119) class="cloudy" ;; -122) class="verycloudy" ;; -143|248|260) class="fog" ;; -176|263|266|293|296|353) class="lightrain" ;; -179|182|185|281|284|311|314|317|350|362|365|374|377) class="hail" ;; -200|386|389|392) class="thunder" ;; -227|320) class="lightsnow" ;; -230|329|332|335|338|371|395) class="heavysnow" ;; -299|302|305|308|356|359): class="heavyrain" ;; -323|326|368) class="snowrain" ;; -esac - -echo "${data}" | jq \ - --raw-output \ - --unbuffered \ - --compact-output \ - --arg class "${class}" \ - --arg tooltip "$(curl -s v2.wttr.in/"${loc}"?ATFQ | tail -n5)" \ - '.current_condition[] | { text: .weatherDesc[0].value, percentage: (.temp_C | tonumber), class: $class, alt: $class, tooltip: ($tooltip) }' - diff --git a/.config/waybar/style.css b/.config/waybar/style.css deleted file mode 100644 index 01a0084..0000000 --- a/.config/waybar/style.css +++ /dev/null @@ -1,390 +0,0 @@ -/* - * vim: fdm=marker fdl=1 - * */ - -/* start flavours */ -@define-color base00 #0c0c0c; -@define-color base01 #db4d6d; -@define-color base02 #5dac81; -@define-color base03 #fad689; -@define-color base04 #58b2dc; -@define-color base05 #69b0ac; -@define-color base06 #70649a; -@define-color base07 #bdc0ba; -@define-color base08 #1c1c1c; -@define-color base09 #cb1b45; -@define-color base0A #86c166; -@define-color base0B #f7d94c; -@define-color base0C #2ea9df; -@define-color base0D #81c7d4; -@define-color base0E #8a6bbe; -@define-color base0F #fffffb; - -* { - font-family: Iosevka Etoile, Sarasa Fixed J, Material Design Icons; - font-size: 9pt; -} -/* end flavours */ - -@define-color accent @base06; -@define-color accentdarker @base0E; -@define-color foreground @base07; -@define-color background @base00; -/* @define-color background rgba(12, 12, 12, 0.96); */ -@define-color dimmed #5e5e5e; -@define-color dimmeddarker #434343; -@define-color urgent @base09; - -* { - border: none; - border-radius: 0; -} - -window#waybar { - background: @background; - color: @foreground; - /* padding: 0 0.3rem; */ -} - -window#waybar.hidden { - opacity: 0; -} - - -#window, -#mode, -#clock, -#battery, -#cpu, -#memory, -#disk, -#temperature, -#backlight, -#idle_inhibitor, -#network, -#pulseaudio, -#wireplumber, -#custom-toggl, -#custom-gammastep, -#custom-weather, -#custom-mpris, -#custom-todo, -#custom-covid, -#custom-timetracked, -#tray { - /* border-top: 1px solid @dimmeddarker; */ - padding: 0 0.1rem; - margin: 0 0.2rem; - color: @dimmed; -} - -#cpu:hover, -#memory:hover, -#backlight:hover, -#idle_inhibitor:hover, -#network:hover, -#network.tailscale:hover, -#pulseaudio:hover, -#wireplumber:hover, -#custom-mpris:hover, -#custom-gammastep:hover, -#custom-todo:hover { - color: @foreground; - transition-property: background; - transition-duration: 0.1s; -} - -#tags button, -#workspaces button { - padding: 0 5px; - background: transparent; - color: @dimmed; - /* border-bottom: 3px solid transparent; */ -} - -#tags button { - color: @dimmeddarker; -} - -#tags button.occupied { - color: @dimmed; -} - -#workspaces button.visible { - color: @dimmeddarker; - background: @accentdarker; -} - -#tags button.focused, -#workspaces button.focused { - font-weight: bold; - color: @foreground; - background: @accent; - transition-property: background; - transition-duration: 0.01s; -} - -#tags button.urgent, -#workspaces button.urgent { - color: @background; - background: @urgent; -} - -#tags button:hover, -#tags button.focused:hover, -#workspaces button:hover, -#workspaces button.focused:hover { - background: @accent; - color: @foreground; - transition-property: background, color; - transition-duration: 0.01s; - - /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ - box-shadow: inherit; - text-shadow: inherit; -} - -#tags button.urgent:hover, -#workspaces button.urgent:hover { - background: @foreground; - transition-property: background; - transition-duration: 0.01s; -} - -#mode { - /* font-style: italic; */ - color: @background; - background: @base03; - margin: 3px 6px; - border-radius: 2px; -} - -#clock {} - -#clock.local { - color: @foreground; -} - -#clock.utc {} - -#disk.root {} - -#disk.home { - /* margin-left: 0; */ - /* padding-left: 0; */ -} - -#battery {} - -#battery.charging { - color: @background; - background: @base0A; -} - -@keyframes blink { - to { - background: @foreground; - color: @background; - } -} - -#battery.critical:not(.charging) { - color: @foreground; - background: @urgent; - animation-name: blink; - animation-duration: 0.5s; - animation-timing-function: linear; - animation-iteration-count: infinite; - animation-direction: alternate; -} - -label:focus { - background: @background; -} - -#cpu {} - -#memory {} - -#backlight {} - -#backlight.off { - color: @dimmed; -} - -#network {} - -#network.disconnected { - border-top: 1px solid @urgent; - color: @dimmed; -} - -#network.tailscale.disabled, -#network.tailscale.disconnected, -#network.mullvad.disabled, -#network.mullvad.disconnected { - border-top: 1px solid @dimmeddarker; -} - -#network.tailscale.ethernet, -#network.tailscale.linked, -#network.mullvad.ethernet, -#network.mullvad.linked { - color: @foreground; - border-top: 1px solid @base0E; -} - -#pulseaudio {} - -#pulseaudio.muted { - border-top: 1px solid @urgent; - color: @dimmed; -} - -#pulseaudio.bluetooth { - border-top: 1px solid @base04; -} - -#wireplumber {} - -#wireplumber.muted { - border-top: 1px solid @urgent; - color: @dimmed; -} - -#wireplumber.bluetooth { - border-top: 1px solid @base04; -} - -#temperature {} - -#temperature.critical { - color: @foreground; - background: @urgent; - border-top: none; -} - -#tray {} - -#idle_inhibitor {} - -#idle_inhibitor.activated { - color: @foreground; - border-top: 1px solid @base02; -} - -#mpris { - color: @foreground; -} - -#mpris.playing, -#mpris.paused { - border-top: 1px solid @base04; -} - -#mpris.paused { - font-style: italic; -} - -#mpris.spotify { - border-top: 1px solid #1db954; -} - -#mpris.mpv { - border-top: 1px solid #8f008f; -} - -#custom-toggl { - color: @foreground; - border-top: 1px solid @urgent; -} - -#custom-todo.off { - color: @dimmed; - border-top: 1px solid @dimmeddarker; - padding: 0 0 0 0.4rem; -} - -#custom-todo.on { - color: @foreground; - border-top: 1px solid @urgent; - font-weight: bold; - padding: 0 0.6rem 0 0.4rem; -} - -#custom-todo.work { - background: @urgent; -} - -#custom-timetracked { - color: @urgent; - border-top: 1px solid @urgent; -} - -@keyframes flash { - 50% { - background: rgba(255, 174, 66, 0.7); - color: @background; - } -} - -#custom-gamma.night { - border-top: 1px solid @base0C; - color: @foreground; - animation-name: flash; - animation-duration: 0.3s; - animation-timing-function: linear; - animation-iteration-count: 1; -} - -#custom-gamma.day { - color: @dimmed; -} - -#custom-gamma.off { - border-top: 1px solid @urgent; - color: @dimmed; -} - -#custom-weather { - color: @dimmed; -} - -#custom-covid.green { - /* border-top: 1px solid #00cc00; */ - /* color: #00cc00; */ -} - -#custom-covid.yellow { - /* border-top: 1px solid #f7dd31; */ - /* color: #f7dd31; */ -} - -#custom-covid.orange { - /* border-top: 1px solid #faa31b; */ - /* color: #faa31b; */ -} - -#custom-covid.red { - /* border-top: 1px solid #f92206; */ - /* color: #f92206; */ -} - -#custom-covid.darkred { - /* border-top: 1px solid #c01a00; */ - /* color: #c01a00; */ -} - -#custom-covid.darkdarkred { - /* border-top: 1px solid #941100; */ - /* color: #941100; */ -} - -#custom-hotspots { - border-top: 1px solid @urgent; - color: @dimmed; -} - -#custom-hotspots.soon { - color: @urgent; -} |