;; weather import (defpoll ICON :interval "15m" `~/.config/eww/scripts/weather_info --icon`) (defpoll STAT :interval "15m" `~/.config/eww/scripts/weather_info --stat`) (defpoll TEMP :interval "5m" `~/.config/eww/scripts/weather_info --temp`) (defpoll HEX :interval "15m" `~/.config/eww/scripts/weather_info --hex`) (defpoll QUOTE :interval "15m" `~/.config/eww/scripts/weather_info --quote`) (defpoll QUOTE2 :interval "15m" `~/.config/eww/scripts/weather_info --quote2`) ;;Time Date Weather ------------------------------------------------------ (defwidget time [] (box :class "box" :orientation "h" :space-evenly true (label :class "time" :text "${time}" :halign "center" :hexpand true))) (defpoll time :interval "1s" "date '+%I:%M:%S %P'") (defwindow time :monitor 1 :geometry (geometry :x "0.5%" :y "2%" :width "270px" :height "70px" :anchor "bottom left") :stacking "bottom" (time)) (defpoll date :interval "1s" "date '+%A %D'") (defwidget date [] (box :class "box" :orientation "h" :space-evenly false (label :class "date" :text "${date}" :xalign 0))) (defwidget weather [] (box :class "box" :orientation "h" :space-evenly false (label :class "date" :text "${ICON}${TEMP}" :halign "center" :hexpand true))) (defwindow date :monitor 1 :geometry (geometry :x "440" :y "2%" :width "467px" :height "70px" :anchor "bottom left") :stacking "bottom" (date)) (defwindow weather :monitor 1 :geometry (geometry :x "285" :y "2%" :width "145px" :height "70px" :anchor "bottom left") :stacking "bottom" (weather)) ;; --- Listeners & Polls --- ;; Use `deflisten` with `playerctl --follow` to react to player events ;; efficiently. When a player quits, `playerctl` exits, and the `|| echo` ;; part provides a default value, ensuring the UI updates correctly. (deflisten song_title :initial "No Music Playing" "playerctl metadata --format '{{title}}' --follow || echo 'No Music Playing'") (deflisten song_artist :initial "Unknown Artist" "playerctl metadata --format '{{artist}}' --follow || echo 'Unknown Artist'") (deflisten player_status :initial "Stopped" "playerctl metadata --format '{{status}}' --follow || echo 'Stopped'") ;; Polling is still needed for things that change continuously, like position, ;; but we can use longer, more efficient intervals. (defpoll song_length_s :interval "2s" :initial "1" "playerctl metadata mpris:length | awk '{print $1 / 1000000}' || echo 1") (defpoll song_position_s :initial "0" :interval "1s" "playerctl position || echo 0") (defpoll formatted_position :interval "1s" "playerctl position -f '{{duration(position)}}' || echo '0:00'") ;; Cover art and volume can also be polled at a slower rate. (defpoll cover_art_path :interval "1s" "$HOME/.config/eww/get-cover.sh") ;; Cava runs as a persistent listener, which is correct. (deflisten cava :initial "" "bash $HOME/.config/eww/cava.sh") ;; --- Widget Definition --- (defwidget music-widget [] (box :class "music-widget" :orientation "h" :space-evenly false (box :class "cover-art" :style "background-image: url('${cover_art_path}');") (box :class "music-info" :orientation "v" :space-evenly false (label :class "song-title" :text song_title :limit-width 25) (label :class "artist" :text song_artist :limit-width 25) (box :class "controls" :orientation "h" (button :onclick "playerctl previous" "󰒮") (button :onclick "playerctl play-pause" {player_status == "Playing" ? "󰏤" : "󰐊"}) (button :onclick "playerctl next" "󰒭")) (label :class "position" :text formatted_position) (scale :class "progress-bar" :min 0 :max song_length_s :value song_position_s :onchange "playerctl position {}") (label :class "cava-visualizer" :text cava) ) ) ) ;; --- Window Definition --- (defwindow music-widget :monitor 1 :stacking "bottom" :geometry ( geometry :x "467px" :y "10px" :width "440px" :height "120px" ) :wm-ignore true (music-widget)) ;;---------------------------------------------------------------------------------------- ;;status widget (defwidget spacer [] (box :class "spacer")) (defwidget cpu [] (system-progress :class "cpu" :tip "CPU ${round(EWW_CPU.avg,1)}%" :value {round(EWW_CPU.avg, 0)} :icon "" :pct "${round(EWW_CPU.avg, 0)}%")) (defwidget cput [] (system-progress :class "cput" :tip "CPU Temp ${EWW_TEMPS["CORETEMP_PACKAGE_ID_0"]}°C" :value {((EWW_TEMPS["CORETEMP_PACKAGE_ID_0"] - 25) / 75) * 100} :icon "" :pct "${EWW_TEMPS["CORETEMP_PACKAGE_ID_0"]}°")) (defpoll gput :interval "2s" :initial "0" "nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits") (defwidget gput [] (system-progress :class "gput" :tip "GPU Temp ${gput}°C" :value {((gput - 25) / 75) * 100} :icon "" :pct "${gput}°")) (defpoll gpu :interval "2s" :initial "0" "nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits") (defwidget gpu [] (system-progress :class "gpu" :tip "GPU ${gpu}%" :value {gpu} :icon "" :pct "${gpu}%")) (defwidget ram [] (system-progress :class "ram" :tip "RAM ${round(EWW_RAM.used_mem / 1048576, 1)}MB" :value {round(EWW_RAM.used_mem_perc, 0)} :icon "" :pct "${round(EWW_RAM.used_mem / 34359738368 * 100, 0)}%")) (defwidget swap [] (system-progress :class "swap" :tip "Swap ${round((EWW_RAM.total_swap - EWW_RAM.free_swap) / 1048576, 1)}MB" :value {round((EWW_RAM.total_swap - EWW_RAM.free_swap) / EWW_RAM.total_swap * 100, 0)} :icon "" :pct "${round((EWW_RAM.total_swap - EWW_RAM.free_swap) / EWW_RAM.total_swap * 100, 0)}%")) (defwidget netdown [] (system-progress :class "netdown" :tip "Down ${round(EWW_NET["eno1"].NET_DOWN / 1048576, 1)} MB/s" :value {min(max(log(EWW_NET["eno1"].NET_DOWN / 1024 + 1, 10000) * 100, 0), 100)} :icon "󰇚" :pct {EWW_NET["eno1"].NET_DOWN / 1048576 > 1 ? "${round(EWW_NET["eno1"].NET_DOWN / 1048576, 1)}M" : "${round(EWW_NET["eno1"].NET_DOWN / 1024, 0)}Kb"})) (defwidget netup [] (system-progress :class "netup" :tip "Up ${round(EWW_NET["eno1"].NET_UP / 1048576, 1)} MB/s" :value {min(max(log(EWW_NET["eno1"].NET_UP / 1024 + 1, 10000) * 100, 0), 100)} :icon "󰕒" :pct {EWW_NET["eno1"].NET_UP / 1048576 > 1 ? "${round(EWW_NET["eno1"].NET_UP / 1048576, 1)}M" : "${round(EWW_NET["eno1"].NET_UP / 1024, 0)}Kb"})) (defwidget disk [] (system-progress :class "disk" :tip "SSD ${round(EWW_DISK["/"].used_perc, 1)}%" :value {round(EWW_DISK["/"].used_perc, 0)} :icon "" :pct "${round(EWW_DISK["/"].used_perc, 1)}%")) ;;-------------------------------------------------------------------------------------------- (defwidget systemwidget [] (box :class "system box" :orientation "h" :spacing 10 :space-evenly false (box :orientation "v" :spacing 8 :space-evenly false :hexpand false (image :path "/home/lorkan/cpu.svg" :image-width 40 :image-height 40) (box :orientation "h" :spacing 8 :space-evenly true :hexpand true (cpu) (cput))) (box :class "spacer" :orientation "v" :hexpand false) (box :orientation "v" :spacing 8 :space-evenly false :hexpand false (image :path "/home/lorkan/gpu.svg" :image-width 40 :image-height 40) (box :orientation "h" :spacing 8 :space-evenly true :hexpand true (gpu) (gput))) (box :class "spacer" :orientation "v" :hexpand false) (box :orientation "v" :spacing 8 :space-evenly false :hexpand false (image :class "svg" :path "/home/lorkan/ram.png" :image-width 40 :image-height 40) (box :orientation "h" :spacing 8 :space-evenly true :hexpand true (ram) (swap))) (box :class "spacer" :orientation "v" :hexpand false) (box :orientation "h" :spacing 8 :space-evenly true :hexpand true (netdown) (netup) (disk)))) (defwidget system-progress [class value icon pct tip] (box :class "progress" :orientation "v" :spacing 0 (progress :orientation "v" :flipped true :class class :value value :halign "center" :tooltip tip) (box :orientation "v" (label :class "label" :text icon :halign "center") (label :class "label2" :text pct :halign "center")))) (defwindow status :monitor 1 :geometry (geometry :x "10px" :y "10px" :width "80px" :height "30px" :anchor "top l") :stacking "bottom" (systemwidget))