diff --git a/eww/eww-battery-monitor b/eww/eww-battery-monitor new file mode 100755 index 0000000..f79455b --- /dev/null +++ b/eww/eww-battery-monitor @@ -0,0 +1,119 @@ +#!/usr/bin/env -S awk -f +# -*- mode: awk -*- +function get_icon(charge) { + if (charge <= 10) { + return "󰂃"; + } else if (charge <= 20) { + return "󰁻"; + } else if (charge <= 30) { + return "󰁼"; + } else if (charge <= 40) { + return "󰁽"; + } else if (charge <= 50) { + return "󰁾"; + } else if (charge <= 60) { + return "󰁿"; + } else if (charge <= 70) { + return "󰂀"; + } else if (charge <= 80) { + return "󰂁"; + } if (charge < 100) { + return "󰂂"; + } else { + return "󰁹" + } +} + +function notify_send(title, desc, id) { + if (!id) { + cmd="dunstify -t 0 -p \"" title "\" \"" desc "\"" + while ((cmd | getline id) > 0) { } + close(cmd) + } else { + system("dunstify -r " id " \"" title "\" \"" desc "\"") + } + return id +} + +function close_notify(id) { + system("dunstify -C " id) +} + +function warn_if_low() { + percentage = state_info["percentage"] + id = state_info["id"] + notified = state_info["notified"] + if (percentage <= 10) { + if (!notified) { + state_info["id"] = notify_send("Battery Low", percentage "%", id) + state_info["notified"] = 1 + } + } else if (notified) { + close_notify(id) + state_info["notified"] = 0 + } +} + +function print_state() { + percentage = state_info["percentage"] + printf "%s%s%d%%\n", + get_icon(percentage), + state_info["charging"] ? "󱐋" : "", + percentage + fflush() +} + +function parse_record(record, exit_on_absent) { + split(record, fields) + for (i in fields) { + match(fields[i], /^ *([^:]+): *(.+)$/, parts) + if (length(parts) >= 3) { + props[parts[1]] = parts[2] + } + } + name = props["native-path"] + if ((! BATTERY && props["power supply"] == "yes" && \ + props["native-path"] ~ /BAT[0-9]+/) || name == BATTERY) { + state_info["percentage"] = props["percentage"] + 0 + return 1 + } else if ((! ADAPTER && props["power supply"] == "yes" && \ + props["native-path"] ~ /ADP[0-9]+/) || name == ADAPTER) { + state_info["charging"] = (props["online"] == "yes") + return 1 + } else { + return 0 + } +} + +function print_initial_stats() { + cmd = "upower --dump" + found = 0 + while ((cmd | getline record) > 0) { + if (record ~ /Device: \/org\/freedesktop\/UPower\/devices\// \ + && parse_record(record)) { + found = 1 + } + } + close(cmd) + if (! found) { + # we found no battery adapters + exit 1 + } + print_state() + warn_if_low() +} + +BEGIN { + RS = "" + FS = "\n" + print_initial_stats() + cmd = "upower --monitor-detail" + while ((cmd | getline record) > 0) { + if (record ~ /device changed/) { + parse_record(record) + print_state() + warn_if_low() + } + } + close(cmd) +} diff --git a/eww-fcitx5-toggle b/eww/eww-fcitx5-toggle similarity index 100% rename from eww-fcitx5-toggle rename to eww/eww-fcitx5-toggle diff --git a/eww/eww-hypr-active-window-listener b/eww/eww-hypr-active-window-listener new file mode 100755 index 0000000..edd2f8c --- /dev/null +++ b/eww/eww-hypr-active-window-listener @@ -0,0 +1,24 @@ +#!/usr/bin/env zsh + +function get-titles-for-monitors { + jq -c --null-input \ + --argjson 'monitors' "$(hyprctl -j monitors)" \ + --argjson 'workspaces' "$(hyprctl -j workspaces)" \ + '[$monitors.[].activeWorkspace.id as $active | + $workspaces.[] | select(.id | IN($active))] | + map({(.monitor): (if .lastwindowtitle == "" then "hyprland" else .lastwindowtitle end)}) | add' +} + +function handle { + case "${1}" in + activewindow\>\>*|openwindow*|closewindow*) + get-titles-for-monitors + ;; + esac +} + +get-titles-for-monitors +socat -U - "unix-connect:/tmp/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" | + while read line; do + handle "${line}" + done diff --git a/eww/eww-hypr-workspace-listener b/eww/eww-hypr-workspace-listener new file mode 100755 index 0000000..f52e72e --- /dev/null +++ b/eww/eww-hypr-workspace-listener @@ -0,0 +1,70 @@ +#!/usr/bin/env zsh + +function update-workspaces { + if ((${urgent} != 0)); then + jq -e --null-input \ + --argjson 'active' "${active}" \ + --argjson 'urgent' "${urgent}" \ + 'any($active.[]; .active == $urgent)' >/dev/null && urgent=0 + fi + jq --null-input -c \ + --argjson 'existing' "${existing}" \ + --argjson 'active_id' "${active}" \ + --argjson 'always_show' '[1,2,3,4,5,6,7,8,9]' \ + --argjson 'urgent_id' "${urgent}" \ + '$existing | map_values([.[], ($always_show.[] | + {id: ., name: . | tostring, windows: 0, monitor: null})] | + unique_by(.name) | + map((.monitor != null and + .id == $active_id.[.monitor].active) as $active | + (.id == $urgent_id and ($active | not) and .monitor != null) as $urgent | + if (((.name | startswith(".")) and ($active | not)) + or ((.name == "special") and (.id == -99))) then empty else + .class = (if $active then "hypr-ws-button-active" + else if $urgent then "hypr-ws-button-urgent" + else "hypr-ws-button" end end) | + .changecmd = ((try "~/.config/hypr/scripts/switch-workspace switch \(.name | tonumber)" + catch empty) // "hyprctl dispatch workspace \(.id)") end))' +} + +function get-workspaces { + hyprctl -j workspaces | \ + jq '[group_by(.monitor).[] | {(.[0].monitor): (. | .[0].monitor as $mon | map({id: .id, windows: .windows, name: .name, monitor: $mon}))}] | add' +} + +function get-active { + hyprctl -j monitors | \ + jq -c 'map({(.name): {active: .activeWorkspace.id}}) | add' +} + +# args: (address: string) +function get-workspace-for-window-address { + hyprctl -j clients | jq --arg 'addr' "0x${1}" \ + '.[] | select(.address == $addr) | .workspace.id' +} + +function handle { + case "${1}" in + urgent\>\>*) + urgent="$(get-workspace-for-window-address "${1:8}")" + update-workspaces + ;; + workspace\>\>*) + active="$(get-active)" + update-workspaces + ;; + openwindow*|closewindow*|*workspace*|movewindow*) + existing="$(get-workspaces)" + update-workspaces + ;; + esac +} + +let urgent=0 +local active="$(get-active)" +local existing="$(get-workspaces)" +update-workspaces +socat -U - "unix-connect:/tmp/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" | + while read line; do + handle "${line}" + done diff --git a/eww/eww-network b/eww/eww-network new file mode 100755 index 0000000..7094119 --- /dev/null +++ b/eww/eww-network @@ -0,0 +1,15 @@ +#!/usr/bin/env zsh + +if [[ "$(uname)" = 'Linux' ]]; then + local active_networks="$(nmcli c s --active)" + local output='' + [[ "${active_networks}" = *' wifi '* ]] && output="${output}󰖩 " + [[ "${active_networks}" = *' ethernet '* ]] && output="${output}󰈁" + [[ "${active_networks}" = *' wireguard '* ]] && output="${output}󰖂 " + (( ${#output} == 0 )) && output='󰈂' + bluetoothctl show | grep 'Powered: yes' >/dev/null && output="${output}  " + printf '%s\n' "${output}" +else + echo "${0}: error: unknown os: \"$(uname)\"" >&2 + exit 1 +fi diff --git a/eww/eww-pulse-listener b/eww/eww-pulse-listener new file mode 100755 index 0000000..1d978de --- /dev/null +++ b/eww/eww-pulse-listener @@ -0,0 +1,26 @@ +#!/usr/bin/env zsh + +function print-volume { + let volume="$(pamixer --get-volume)" + local icon + if [[ "$(pamixer --get-mute)" = "true" ]]; then + icon='󰸈' + elif ((${volume} > 50)); then + icon='󰕾' + elif ((${volume} >= 0)); then + icon='󰖀' + else + icon='?' + fi + printf '%s%3d%%\n' "${icon}" "${volume}" +} + +print-volume +pactl subscribe | \ + while read line; do + case "${line}" in + "Event 'change' on sink"*) + print-volume + ;; + esac + done diff --git a/eww-toggle-systray b/eww/eww-toggle-systray similarity index 100% rename from eww-toggle-systray rename to eww/eww-toggle-systray