3PLW22JL4I4ZXBYEVFQWVREK4PU3UW2A2OFHUQKN7KWLGB3O4UTAC KAREPDTUFLSHROK53ZCZ24VWRRTDNLBICMI7K3UUJMN4X4P4OL4QC DWUHKA7TDWTRK3PZGFJR6ZXJ7Q2GO4R24SMYFL7LS2VW2KNV3I6QC RPGBGVR75LTVQ7OV2WIJV5PTTF5D7QDJSJI2MPEY4HPHCWWIY3WQC EG4DUC4NREW5NTDKCRTDRFTPVDAYCGT4TGU2Y3XC43HHTYQPHA3AC H3GYCX27WTONFBIJN7UIV26LJSCENQJC4XXIOEYINXJLEDGKYJJQC EVVP46IQ4U6JEDWVJ4D6KT77ABOMY7XKIO2ITX4DHJDRTGTYCUTQC JOK7DA5XBOK2MIVR7ORTSAEMQ6U5642I537IGUYBX67DPFF5QJ3QC BYZGRIFZY253OFK442SR6X743U4LAX4NLFBQ4XPKXEDPPXNNUM4AC TXA66OLAOYNGEDRBC4SKWDZPLBZXUU7WHDIAYN4TXGEJR6WIJOIQC F26DJCZ7RLGRDZSYACB6MGMNTW7L5FE332EBYEIJTBRK7QJ6ZIYAC NNUJU4U7H6QBAKSVR2N5NGQDODJFAJ6UWFU6N656WU2ORRG7RQRQC (defwidget system-menu [](box:class "system-menu-box":space-evenly false:orientation "v"(box:class "top-row":space-evenly false(label:class "time":text "${time.hour}:${time.minute}")(box:class "date-box":space-evenly false(label:class "date":text {time.date})(label:class "day":text {time.day})))(centerbox:class "system-row"(box:class "wifi-box":space-evenly false:orientation "v"(box:class "element icon ${net.class}":space-evenly false(button:class "wifi-button":onclick "scripts/net toggle"{net.icon})(label:class "separator":text "│")(button:class "wifi-arrow-btn":onclick "eww close system-menu && gnome-control-center &"""))(label:text {net.essid}:xalign 0.5:limit-width 15))(box:class "bluetooth-box":space-evenly false:orientation "v"(box:class "element icon ${bluetooth.class}":space-evenly false(button:class "bluetooth-button":onclick "scripts/bluetooth toggle"{bluetooth.icon})(label:class "separator":text "│")(button:class "bluetooth-arrow-btn":onclick "eww close system-menu && blueberry"""))(label:text {bluetooth.text}:xalign 0.5:tooltip "${bluetooth.text} ${bluetooth.battery}":limit-width 15))(box:class "airplane-box":space-evenly false:orientation "v"(box:class "element"(button:class "airplane-button":onclick "scripts/airplane toggle"airplane))(label:text "Airplane Mode":xalign 0.5:limit-width 16)))(box:class "sliders":orientation "v"(box:class "volume-slider-box":space-evenly false(button:class "volume-icon icon":onclick "scripts/volume mute SINK"{volume.icon})(scale:class "volume-bar":value {volume.percent}:tooltip "volume on ${volume.percent}%":onchange "scripts/volume setvol SINK {}"))(box:class "brightness-slider-box":space-evenly false(button:class "brightness-slider-icon icon"{brightness.icon})(scale:class "brightness-slider":value {brightness.percent}:marks true:onchange "light -S {}")))(box:class "system-info-box"; cpu(box:class "sys-box":space-evenly false:halign "start"(circular-progress:value "${EWW_CPU.avg}":class "sys-cpu":thickness 3(label:text "":class "sys-icon-cpu icon"))(box:orientation "v":vexpand false(label:text "cpu":halign "start":class "sys-text-cpu")(label:text "${round(EWW_CPU.avg,2)}%":halign "start":class "sys-text-sub")(label:text "${EWW_CPU.cores[0].freq} MHz":halign "start":class "sys-text-sub"))); memory(box:class "sys-box":space-evenly false:halign "end"(circular-progress:value {memory.percent}:class "sys-mem":thickness 3(label:text "":class "sys-icon-mem icon"))(box:orientation "v"(label:text "memory":halign "start":class "sys-text-mem")(label:text "${memory.used} | ${memory.total}":halign "start":class "sys-text-sub"))))(centerbox:class "bottom-row"(box:class "battery-box":space-evenly false:halign "start"(label:class "battery-icon icon":style "color: ${battery.color}":text {battery.icon})(label:text {EWW_BATTERY["BAT0"].capacity})(label:class "battery-status":text {battery.status})(label:class "battery-wattage":text {battery.wattage}))(label)(box:space-evenly false:halign "end"(button:halign "end":class "power-button icon":onclick "wlogout -p layer-shell &""")))))(defwindow system-menu:stacking "fg":monitor 0:geometry (geometry:x "0":y "0":width "0%":height "0%":anchor "right top")(system-menu))
(defwidget osd-part [icon value class](box:class "osd-part osd-${class}":orientation "v":space-evenly false(scale:flipped true:orientation "v":value value)(label:text icon)))(defwidget osd [](box:class "osd-container":space-evenly false(revealer:reveal {osd-brightness}:transition "slideright"(osd-part:class "brightness":icon {brightness.icon}:value {brightness.percent}))(revealer:reveal {osd-volume}:transition "slideright"(osd-part:class "volume":icon {volume.icon}:value {volume.percent}))))(defwindow osd:stacking "fg":focusable false:monitor 0:geometry (geometry:x "1%":y "0%":width "0%":height "0%":anchor "center left")(osd))
(defwidget music [](box:class "music-window":space-evenly false:style "background-color: ${music.color1}; border: 1px solid ${music.color2};"(box:class "music-cover-art":style "background-image: url(\"${music.cover}\");")(box:orientation "v":class "music-box"(label:class "music-title":wrap true:text {music.title})(label:class "music-artist":wrap true:text {music.artist})(centerbox:halign "center":class "music-button-box icon"(button :class "music-button" :onclick "playerctl previous" "")(button :class "music-button" :onclick "playerctl play-pause" {music.status})(button :class "music-button" :onclick "playerctl next" ""))(box:orientation "v"(box(label:xalign 0:class "music-time":text {music.position_time})(label:xalign 1:class "music-time":text {music.length}))(box:class "music-bar"(scale; doesn't work, looking for other ways; :style "background: linear-gradient(to right, ${music.color1}, ${music.color2});":onchange "playerctl position `bc <<< \"{} * $(playerctl metadata mpris:length) / 1000000 / 100\"`":value {music.position}))))))(defwindow music:stacking "fg":focusable false:monitor 0:geometry (geometry:x "0%":y "0%":width "0%":height "0%":anchor "top center")(music))
(defwidget calendar-win [](box:class "calendar-win"(calendar)))(defwindow calendar:monitor 0:geometry (geometry:x "0%":y "0%":anchor "top right":width "0px":height "0px")(calendar-win))
#!/usr/bin/env bash# define colors# red peach green bluecolors=("#f38ba8" "#fab387" "#a6e3a1" "#89b4fa")# pink yellow teal lavenderdimmed=("#f5c2e7" "#f9e2af" "#94e2d5" "#b4befe")empty="#313244"# get initial focused workspacefocusedws=$(hyprctl -j monitors | jaq -r '.[] | select(.focused == true) | .activeWorkspace.id')declare -A o=([1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=0 [8]=0 [9]=0 [10]=0)declare -A monitormapdeclare -A workspaces# set color for each workspacestatus() {if [ "${o[$1]}" -eq 1 ]; thenmon=${monitormap[${workspaces[$1]}]}if [ "$focusedws" -eq "$1" ]; thenecho -n "${colors[$mon]}"elseecho -n "${dimmed[$mon]}"fielseecho -n "$empty"fi}# handle workspace create/destroyworkspace_event() {o[$1]=$2while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')}# handle monitor (dis)connectsmonitor_event() {while read -r k v; do monitormap["$k"]=$v; done < <(hyprctl -j monitors | gojq -r '.[]|"\(.name) \(.id) "')}# get all apps titles in a workspaceapplist() {ws="$1"apps=$(hyprctl -j clients | jaq -jr '.[] | select(.workspace.id == '"$ws"') | .title + "\\n"')echo -En "${apps%"\n"}"}# generate the json for ewwgenerate() {echo -n '['for i in {1..10}; doecho -n ''"$([ "$i" -eq 1 ] || echo ,)" '{ "number": "'"$i"'", "color": "'"$(status "$i")"'" }' #, "tooltip": "'$(applist "$i")'" }'doneecho ']'}# setup# add monitorsmonitor_event# add workspaceswhile read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')# check occupied workspacesfor num in "${!workspaces[@]}"; doo[$num]=1done# generate initial widgetgenerate# main loopsocat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "workspace|mon(itor)?" | while read -r line; docase ${line%>>*} in"workspace")focusedws=${line#*>>};;"focusedmon")focusedws=${line#*,};;"createworkspace")workspace_event "${line#*>>}" 1;;"destroyworkspace")workspace_event "${line#*>>}" 0;;"monitor"*)monitor_event;;esacgeneratedone
#!/usr/bin/env bashvolicons=("" "" "")if [ ! "$XDG_CACHE_HOME" ]; thenXDG_CACHE_HOME="/home/mihai/.local/cache"fidate="$XDG_CACHE_HOME/eww/osd_vol.date"vol() {wpctl get-volume @DEFAULT_AUDIO_"$1"@ | awk '{print int($2*100)}'}ismuted() {wpctl get-volume @DEFAULT_AUDIO_"$1"@ | rg -i mutedecho $?}setvol() {wpctl set-volume @DEFAULT_AUDIO_"$1"@ "$(awk -v n="$2" 'BEGIN{print (n / 100)}')"}setmute() {wpctl set-mute @DEFAULT_AUDIO_"$1"@ toggle}osd() {if [ ! -f "$date" ]; thenmkdir -p "$XDG_CACHE_HOME/eww"fidate +%s > "$date"}osd_handler() {lock=0rundate=0if [ ! -f "$date" ]; thenmkdir -p "$XDG_CACHE_HOME/eww"echo 0 > "$date"fiwhile true; do# get datesrundate=$(cat "$date")currentdate=$(date +%s)# handle showingif [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; theneww open osdeww update osd-volume=truelock=1elif [ "$((currentdate - rundate))" = "2" ] && [ "$lock" -eq 1 ]; theneww update osd-volume=falselock=0if [ "$(eww get osd-volume)" = "false" ] && [ "$(eww get osd-brightness)" = "false" ]; theneww close osdfifisleep 0.1doneeww close osd}if [ "$1" = "mute" ]; thenif [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; thenecho "Can only mute SINK or SOURCE"; exit 1fisetmute "$2"elif [ "$1" = "setvol" ]; thenif [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; thenecho "Can only set volume for SINK or SOURCE"; exit 1elif [ "$3" -lt 1 ] || [ "$3" -gt 100 ]; thenecho "Volume must be between 1 and 100"; exit 1fisetvol "$2" "$3"elif [ "$1" = "osd" ]; thenosdelse# initial valueslvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')ismuted=$(ismuted "SINK")if [ "$ismuted" = 1 ]; thenicon="${volicons[$lvl]}"elseicon=""fiecho '{ "icon": "'"$icon"'", "percent": "'"$(vol "SINK")"'", "microphone": "'"$(vol "SOURCE")"'" }'osd_handler &# event looppactl subscribe | rg --line-buffered "change" | while read -r _; dolvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')ismuted=$(ismuted "SINK")if [ "$ismuted" = 1 ]; thenicon="${volicons[$lvl]}"elseicon=""fiecho '{ "icon": "'"$icon"'", "percent": "'"$(vol "SINK")"'", "microphone": "'"$(vol "SOURCE")"'" }'donefi
#!/usr/bin/env bashtoggle() {status=$(rfkill -J | jaq -r '.rfkilldevices[] | select(.type == "wlan") | .soft' | head -1)if [ "$status" = "unblocked" ]; thenrfkill block wlanelserfkill unblock wlanfi}if [ "$1" = "toggle" ]; thentoggleelsewhile true; dostatus=$(nmcli -f state g| tail -1)wifistatus=$(nmcli -t -f in-use,ssid,signal dev wifi | rg '\*' | sed 's/\"/\\"/g')signal=$(echo "$wifistatus" | awk -F: '{print $3}')essid=$(echo "$wifistatus" | awk -F: '{print $2}')icons=("" "" "" "" "")if [ "$status" = "disconnected" ] ; thenicon=""color="#988ba2"class=""elselevel=$(awk -v n="$signal" 'BEGIN{print int((n-1)/20)}')if [ "$level" -gt 4 ]; thenlevel=4fiicon=${icons[$level]}color="#cba6f7"class="wifi-connected"fiecho '{ "essid": "'"$essid"'", "icon": "'"$icon"'", "color": "'"$color"'", "class": "'"$class"'" }'sleep 3donefi
#!/usr/bin/env bashget_status() {s=$1if [ "$s" = "Playing" ]; thenecho ""elseecho ""fi}get_length_sec() {len=$1if [ -z "$len" ]; thenecho 0elsebc <<< "$len / 1000000"fi}get_length_time() {len=$1if [ -n "$len" ]; thenlen=$(bc <<< "$len / 1000000 + 1")date -d@"$len" +%M:%Selseecho ""fi}get_position() {pos=$1len=$2if [ -n "$pos" ]; thenbc -l <<< "$pos / $len * 100"elseecho 0fi}get_position_time() {pos=$1len=$2if [ -n "$pos" ]; thendate -d@"$(bc <<< "$pos / 1000000")" +%M:%Selseecho ""fi}get_cover() {mkdir -p "$XDG_CACHE_HOME/eww_covers"cd "$XDG_CACHE_HOME/eww_covers" || exitIMGPATH="$XDG_CACHE_HOME/eww_covers/cover_art.png"COVER_URL="$1"if [[ "$COVER_URL" = https* ]]; thenif [ ! -e "$XDG_CACHE_HOME/eww_covers/$(basename "$COVER_URL")" ]; thenwget -N "$COVER_URL" -o /dev/nullfirm "$IMGPATH"ln -s "$(basename "$COVER_URL")" "$IMGPATH"IMG="${IMGPATH}"elif [ "$COVER_URL" = "" ]; thenIMG=""elseIMG="$COVER_URL"fiecho "$IMG"}sanitize() {echo "$1" | sed 's/"/\"/g'}prevCover=''playerctl -F metadata -f '{{title}}\{{artist}}\{{status}}\{{position}}\{{mpris:length}}\{{mpris:artUrl}}' 2>/dev/null | while IFS="$(printf '\')" read -r title artist status position len cover; doif [[ "$cover" != "$prevCover" ]]; thenCOVER=$(get_cover "$cover")if [ "$COVER" != "" ]; thencols=$(convert "$COVER" -colors 2 -format "%c" histogram:info: | awk '{print $3}')color1=$(echo "$cols" | head -1)color2=$(echo "$cols" | tail -1)elsecolor1="#1e1e2e"color2="#28283d"fifijaq --null-input -r -c \--arg artist "$(sanitize "$artist")" \--arg title "$(sanitize "$title")" \--arg status "$(get_status "$status")" \--arg pos "$(get_position "$position" "$len")" \--arg pos_time "$(get_position_time "$position" "$len")" \--arg length "$(get_length_time "$len")" \--arg cover "$COVER" \--arg color1 "$color1" \--arg color2 "$color2" \'{"artist": $artist, "title": $title, "status": $status, "position": $pos, "position_time": $pos_time, "length": $length, "cover": $cover, "color1": $color1, "color2": $color2}'prevCover=$coverdone
#!/usr/bin/env bashwhile true; do# human-readablefreeH=$(free -h --si | rg "Mem:")# non-human-readablefreeN=$(free --mega | rg "Mem:")total="$(echo "$freeH" | awk '{ print $2 }')"used="$(echo "$freeH" | awk '{ print $3 }')"t="$(echo "$freeN" | awk '{ print $2 }')"u="$(echo "$freeN" | awk '{ print $3 }')"free=$(printf '%.1fG' "$(bc -l <<< "($t - $u) / 1000")")perc=$(printf '%.1f' "$(free -m | rg Mem | awk '{print ($3/$2)*100}')")echo '{ "total": "'"$total"'", "used": "'"$used"'", "free": "'"$free"'", "percent": '"$perc"' }'sleep 3done
#!/usr/bin/env bashicons=("" "" "")if [ ! "$XDG_CACHE_HOME" ]; thenXDG_CACHE_HOME="/home/mihai/.local/cache"fidate="$XDG_CACHE_HOME/eww/osd_brightness.date"osd() {if [ ! -f "$date" ]; thenmkdir -p "$XDG_CACHE_HOME/eww"fidate +%s > "$date"}osd_handler() {lock=0rundate=0if [ ! -f "$date" ]; thenmkdir -p "$XDG_CACHE_HOME/eww"echo 0 > "$date"fiwhile true; do# get datesrundate=$(cat "$date")currentdate=$(date +%s)# handle showingif [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; theneww open osdeww update osd-brightness=truelock=1elif [ "$((currentdate - rundate))" = "2" ] && [ "$lock" -eq 1 ]; theneww update osd-brightness=falselock=0if [ "$(eww get osd-brightness)" = "false" ] && [ "$(eww get osd-volume)" = "false" ]; theneww close osdfifisleep 0.1doneeww close osd}if [ "$1" = "osd" ]; thenosdelseosd_handler &# initialicon=${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}echo '{ "percent": '"$(light)"', "icon": "'"$icon"'" }'udevadm monitor | rg --line-buffered "backlight" | while read -r _; doicon="${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}"echo '{ "percent": '"$(light)"', "icon": "'"$icon"'" }'donefi
#!/usr/bin/env bashtoggle() {status=$(rfkill -J | jaq -r '.rfkilldevices[] | select(.type == "bluetooth") | .soft' | head -1)if [ "$status" = "unblocked" ]; thenrfkill block bluetoothelserfkill unblock bluetoothfi}if [ "$1" = "toggle" ]; thentoggleelsewhile true; dopowered=$(bluetoothctl show | rg Powered | cut -f 2- -d ' ')status=$(bluetoothctl info)name=$(echo "$status" | rg Name | cut -f 2- -d ' ')mac=$(echo "$status" | head -1 | awk '{print $2}' | tr ':' '_')if [[ "$(echo "$status" | rg Percentage)" != "" ]]; thenbattery="$(upower -i /org/freedesktop/UPower/devices/headset_dev_"$mac" | rg percentage | awk '{print $2}' | cut -f 1 -d '%')%"elsebattery=""fiif [ "$powered" = "yes" ]; thenif [ "$status" != "Missing device address argument" ]; thentext="$name"icon=""color="#89b4fa"class="bt-connected"elseicon=""text="Disconnected"color="#45475a"class=""fielseicon=""text="Bluetooth off"color="#45475a"class=""fiecho '{ "icon": "'"$icon"'", "battery": "'"$battery"'", "text": "'"$text"'", "color": "'"$color"'", "class": "'"$class"'" }'sleep 3donefi
#!/usr/bin/env bashicons=("" "" "" "" "" "" "" "")num_icons=$(bc <<< "100 / ${#icons[@]}")geticon() {level=$(awk -v n="$CAPACITY" -v c="$num_icons" 'BEGIN{print int(n/c-1)}')if [[ "$level" -lt 0 ]]; thenlevel=0fiecho "${icons[$level]}"}status() {if [ "$STATE" = "Charging" ]; thenecho -n "charging"if [ "$RATE" -gt 0 ]; thenecho ", $(gettime) left"elseecho ""fielif [ "$STATE" = "Discharging" ]; thenecho "$(gettime)h left"elseecho "fully charged"fi}color() {if [ "$CAPACITY" -le 20 ]; thenecho '#f38ba8'elseecho '#a6e3a1'fi}wattage() {microwatts=1000000echo "$(bc -l <<< "scale=1; $RATE / $microwatts") W"}gettime() {FULL=$(cat /sys/class/power_supply/BAT0/energy_full)NOW=$(cat /sys/class/power_supply/BAT0/energy_now)if [ "$RATE" -gt 0 ]; thenif [ "$STATE" = "Discharging" ]; thenEX="$NOW / $RATE"elseEX="($FULL - $NOW) / $RATE"fidate -u -d@"$(bc -l <<< "$EX * 3600")" +%H:%Mfi}while true; doRATE=$(cat /sys/class/power_supply/BAT0/power_now)CAPACITY=$(cat /sys/class/power_supply/BAT0/capacity)STATE=$(cat /sys/class/power_supply/BAT0/status)echo '{ "icon": "'"$(geticon)"'", "percent": '"$CAPACITY"', "wattage": "'"$(wattage)"'", "status": "'"$(status)"'", "color": "'"$(color)"'" }'sleep 3done
#!/bin/shicon() {if [ "$STATUS" = "no" ]; thenecho ""elseecho ""fi}toggle() {if [ "$STATUS" = "no" ]; thenrfkill block allnotify-send --urgency=normal -i airplane-mode-symbolic "Airplane Mode" "Airplane mode has been turned on!"elserfkill unblock allnotify-send --urgency=normal -i airplane-mode-disabled-symbolic "Airplane Mode" "Airplane mode has been turned off!"fi}if [ "$1" = "toggle" ]; thentoggleelsewhile true; doSTATUS="$(rfkill list | sed -n 2p | awk '{print $3}')"iconsleep 3;donefi
(defwidget workspaces [o](eventbox:onscroll "echo {} | sed -e \"s/up/-1/g\" -e \"s/down/+1/g\" | xargs hyprctl dispatch workspace"(box:class "module workspaces":orientation o:spacing 5(for ws in workspace(button:onclick "hyprctl dispatch workspace ${ws.number}":class "ws icon":style "color: ${ws.color};"; :tooltip {ws.tooltip}"●")))))
(defwidget volume-module [](box:class "module icon"(eventbox:onscroll "echo {} | sed -e 's/up/-/g' -e 's/down/+/g' | xargs -I% wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.005%":onclick "pavucontrol &":onrightclick "scripts/volume mute SINK"(label:class "vol-icon":tooltip "volume ${volume.percent}%":text {volume.icon}))))
(defvar bright_reveal false)(defvar bt_rev false)(defvar music_reveal false)(defvar net_rev false)(defvar time_rev false)(defvar vol_reveal false)(defvar osd-brightness false)(defvar osd-volume false)(defpoll time :interval "5s" `date +'{"date": "%d/%m", "hour": "%H", "minute": "%M", "day": "%A"}'`)(deflisten airplane "scripts/airplane")(deflisten battery "scripts/battery")(deflisten bluetooth "scripts/bluetooth")(deflisten brightness "scripts/brightness")(deflisten memory "scripts/memory")(deflisten music "scripts/music")(deflisten net "scripts/net")(deflisten volume "scripts/volume")(deflisten workspace "scripts/workspaces")
(defwidget sys [](box:class "module":space-evenly false:spacing 5(circular-progress:value "${EWW_CPU.avg}":class "cpubar":thickness 3(button:tooltip "using ${round(EWW_CPU.avg,0)}% cpu":onclick "${EWW_CMD} open --toggle system-menu"(label :class "icon-text" :text "")))(circular-progress:value {memory.percent}:class "membar":thickness 3(button:tooltip "using ${round(memory.percent,0)}% ram":onclick "${EWW_CMD} open --toggle system-menu"(label :class "icon-text" :text "")))(circular-progress:value "${EWW_BATTERY["BAT0"].capacity}":class "batbar":style "color: ${battery.color};":thickness 3(button:tooltip "battery on ${EWW_BATTERY["BAT0"].capacity}%":onclick "${EWW_CMD} open --toggle system-menu"(label :class "icon-text" :text "")))))
(defwidget net [](button:class "module icon":onclick "gnome-control-center &":tooltip {net.essid}:style "color: ${net.color};"{net.icon}))
(defwidget music-module [](eventbox:onhover "${EWW_CMD} update music_reveal=true":onhoverlost "${EWW_CMD} update music_reveal=false"(box:class "module":space-evenly false(box:class "song-cover-art":style "background-image: url(\"${music.cover}\");")(button:class "module":onclick "${EWW_CMD} open --toggle music"{music.title})(revealer:transition "slideright":reveal music_reveal:duration "350ms"(box:class "icon"(button :class "song-button" :onclick "playerctl previous" "")(button :class "song-button" :onclick "playerctl play-pause" {music.status})(button :class "song-button" :onclick "playerctl next" ""))))))
(defvar date_rev false)(defwidget clock_module [](eventbox:onhover "${EWW_CMD} update date_rev=true":onhoverlost "${EWW_CMD} update date_rev=false"(overlay:class "module"(box:space-evenly false(label:text {time.hour}:class "hour")(label:text ":")(label:text {time.minute}:class "minute"))(revealer:reveal date_rev(button:class "date":onclick "${EWW_CMD} open --toggle calendar"{time.date})))))
(defwidget bright [](box:class "module"(eventbox:onscroll "echo {} | sed -e 's/up/-U 1/g' -e 's/down/-A 1/g' | xargs light"(label:text {brightness.icon}:class "bright-icon icon":tooltip "brightness ${round(brightness.percent, 0)}%"))))
(defwidget bluetooth [](button:class "module-bt module icon":onclick "blueberry":onrightclick "scripts/bluetooth toggle":tooltip "${bluetooth.text} ${bluetooth.battery}":style "color: ${bluetooth.color};"{bluetooth.icon}))
(include "./modules/bluetooth.yuck")(include "./modules/bright.yuck")(include "./modules/clock.yuck")(include "./modules/music.yuck")(include "./modules/net.yuck")(include "./modules/sys.yuck")(include "./modules/variables.yuck")(include "./modules/volume.yuck")(include "./modules/workspaces.yuck")(include "./windows/calendar.yuck")(include "./windows/music.yuck")(include "./windows/osd.yuck")(include "./windows/system-menu.yuck")(defwidget left [](box:space-evenly false:halign "start"(workspaces :o "h")))(defwidget right [](box:space-evenly false:halign "end"(net)(sys)(clock_module)))(defwidget center [](box:space-evenly false:halign "center"))(defwidget bar_1 [](centerbox:class "bar":orientation "v"(box :valign "start" (workspaces :o "v"))(box)(box)))(defwidget bar_2 [](centerbox:class "bar"(left)(center)(right)))(defwindow bar_1:monitor 0:geometry (geometry:x "0%":y "0%":width "32px":height "100%":anchor "center left"):stacking "fg":exclusive true(bar_1))(defwindow bar_2:monitor 1:geometry (geometry :x "0%":y "0%":width "100%":height "32px":anchor "top center"):stacking "fg":exclusive true(bar_2))
@import 'css/colors';@mixin rounding {border-radius: 16px;}@mixin window {border: 1px solid $border;box-shadow: 0 2px 3px $shadow;margin: 5px 5px 10px;@include rounding;}* {all: unset;font-family: "Jost *", Roboto, sans-serif;transition: 200ms ease;}@import 'css/calendar';@import 'css/music';@import 'css/osd';@import 'css/sidebar';@import 'css/system';@import 'css/volume';.bar {background-color: $bg;color: $fg;label {font-size: 1.2rem;}}tooltip {background: $bg;border: 1px solid $border;border-radius: 8px;label {font-size: 1rem;}}.icon,.icon label { font-family: Material Symbols Outlined; }.module { margin: 0 5px; }.hour {font-weight: bold;padding-left: 5px;}.minute {padding-right: .7rem;}.date {background: $bg;color: $flamingo;label {font-size: 1.2rem;}}.bright-icon { color: $yellow; }.module-bt { font-size: 1.2rem; }scale trough {background-color: $bg1;border-radius: 24px;margin: 0 1rem;min-height: 10px;min-width: 70px;}.workspaces { margin-left: 10px; }
{config,pkgs,inputs,lib,...}: letdependencies = with pkgs; [config.wayland.windowManager.hyprland.packagecfg.packagebashbcblueberrybluezcoreutilsdbusdunstfindutilsgawkgnome.gnome-control-centergnusedgojqimagemagickjaqlightnetworkmanagerpavucontrolplayerctlprocpspulseaudioripgrepsocatudevupowerutil-linuxwgetwireplumberwlogout];reload_script = pkgs.writeShellScript "reload_eww" ''windows=$(eww windows | rg '\*' | tr -d '*')systemctl --user restart eww.serviceecho $windows | while read -r w; doeww open $wdone'';cfg = config.programs.eww-hyprland;in {options.programs.eww-hyprland = {enable = lib.mkEnableOption "eww Hyprland config";package = lib.mkOption {type = with lib.types; nullOr package;default = pkgs.eww-wayland;defaultText = lib.literalExpression "pkgs.eww-wayland";description = "Eww package to use.";};autoReload = lib.mkOption {type = lib.types.bool;default = false;defaultText = lib.literalExpression "false";description = "Whether to restart the eww daemon and windows on change.";};colors = lib.mkOption {type = with lib.types; nullOr lines;default = null;defaultText = lib.literalExpression "null";description = ''SCSS file with colors defined in the same way as Catppuccin colors are,to be used by eww.Defaults to Catppuccin Mocha.'';};};config = lib.mkIf cfg.enable {home.packages = [cfg.package];# remove nix filesxdg.configFile."eww" = {source = lib.cleanSourceWith {filter = name: _type: letbaseName = baseNameOf (toString name);in!(lib.hasSuffix ".nix" baseName) && !(baseName == "_colors.scss");src = lib.cleanSource ./.;};# links each file individually, which lets us insert the colors file separatelyrecursive = true;onChange =if cfg.autoReloadthen reload_script.outPathelse "";};# colors filexdg.configFile."eww/css/_colors.scss".text =if cfg.colors != nullthen cfg.colorselse (builtins.readFile ./css/_colors.scss);systemd.user.services.eww = {Unit = {Description = "Eww Daemon";# not yet implemented# PartOf = ["tray.target"];PartOf = ["graphical-session.target"];};Service = {Environment = "PATH=/run/wrappers/bin:${lib.makeBinPath dependencies}";ExecStart = "${cfg.package}/bin/eww daemon --no-daemonize";Restart = "on-failure";};Install.WantedBy = ["graphical-session.target"];};};}
.vol-icon { color: $green; }.volbar highlight {background-image: linear-gradient(to right, $teal, $sky);border-radius: 10px;}
.membar {color: $peach;}.cpubar {color: $blue;}.batbar {color: $green;}.membar,.cpubar,.batbar {background-color: $bg1;}.iconmem {color: $peach;}.iconcpu {color: $blue;}.icon-text {font-size: 3rem;padding: .7rem;}.sys-text-sub {color: $text;}.sys-text-mem,.sys-text-cpu {font-size: 1rem;font-weight: bold;}.sys-icon-mem,.sys-icon-cpu {font-size: 1.5rem;margin: 1.5rem;}.system-info-box {@include rounding;background-color: $surface0;margin: .5rem 1rem;padding: .5rem;}.sys-mem,.sys-cpu {background-color: $bg;}.sys-icon-mem,.sys-text-mem,.sys-mem {color: $peach;}.sys-icon-cpu,.sys-text-cpu,.sys-cpu {color: $blue;}.sys-box {margin: .3em;box { margin-left: 1rem; }}
.system-menu-box {@include window;background-color: $bg;border: 1px solid $border;color: $text;}.separator {font-size: 1rem;}.top-row {margin: 1rem 1.5rem 0;.time { font-size: 2rem; }.date-box {margin: 0 1rem;label { font-size: 1.1rem; }.date {background: unset;margin: 0 .5rem 0 0;padding: 0;}}}.system-row {margin: .5rem .7rem;.airplane-box button {padding: 1rem 3rem;}label {font-size: 1rem;margin: 0 .1rem;}}.element {@include rounding;background-color: $surface0;margin: .3rem;button {@include rounding;padding: 1rem;label {font-size: 1.5rem;}&:hover {background-color: $overlay0;}}}.sliders {@include rounding;background-color: $surface0;margin: .5rem 1rem;padding: .6rem 1rem;scale {margin-right: -1rem;min-width: 21.5rem;trough { margin-right: 0; }}box { margin: .2rem 0; }label { font-size: 1.2rem; }}.volume-slider-box,.brightness-slider-box {trough { background-color: $base; }}.volume-bar highlight {@include rounding;background-image: linear-gradient(to right, $teal, $sky);}.brightness-slider-box scale highlight {@include rounding;background-image: linear-gradient(to right, $yellow, $peach);}.bottom-row {margin: .5rem 1rem;.battery-icon { font-size: 2rem; }.battery-wattage { color: $mauve; }.battery-status {color: $subtext0;margin: 0 .5rem;}button {background-color: $surface0;border-radius: 50%;margin-bottom: .1rem;padding: 0 .5rem;label { font-size: 1.5rem; }&:hover { background-color: $overlay0; }}}.bt-connected {background-color: $blue;color: $crust;button:hover { background-color: #7ba2e1; }}.wifi-connected {background-color: $mauve;color: $crust;button:hover { background-color: #b695de; }}
.osd-part {@include window;background: $base;margin: 0 .5rem .5rem;label {color: $text;font-size: 2rem;margin: 0 .1rem 0 .2rem;}scale {margin: -.2rem 0;}trough {@include rounding;background-color: $bg1;margin: 1rem 0 .5rem;min-height: 10rem;min-width: .7rem;highlight {@include rounding;min-width: 0;}}}.osd-volume highlight {background-image: linear-gradient(to top, $teal, $sky);}.osd-brightness highlight {background-image: linear-gradient(to top, $yellow, $peach);}
.song-cover-art {@include rounding;background-position: center;background-size: cover;margin: 4px 5px 4px 0;min-height: 24px;min-width: 24px;}.music-window {@include window;background-color: $bg;border: 1px solid $border;color: $fg;}.music-cover-art {background-position: center;background-size: cover;border-radius: 8px;margin: 1em;min-height: 170px;min-width: 170px;}.music-box {margin: 1rem 1rem 1rem 0;}.music-title {font-size: 1.1rem;font-weight: bold;}.music-artist {color: $subtext1;}.music-button label {color: $subtext1;font-size: 2rem;}.music-time {color: $subtext1;margin: 0 1rem;}.music-bar scale {highlight {background-image: linear-gradient(to right, $teal, $sky);border-radius: 24px;}trough {background-color: $bg1;border-radius: 24px;margin-top: 0;min-height: 10px;min-width: 170px;}}
$rosewater: #f5e0dc;$flamingo: #f2cdcd;$pink: #f5c2e7;$mauve: #cba6f7;$red: #f38ba8;$maroon: #eba0ac;$peach: #fab387;$yellow: #f9e2af;$green: #a6e3a1;$teal: #94e2d5;$sky: #89dceb;$sapphire: #74c7ec;$blue: #89b4fa;$lavender: #b4befe;$text: #cdd6f4;$subtext1: #bac2de;$subtext0: #a6adc8;$overlay2: #9399b2;$overlay1: #7f849c;$overlay0: #6c7086;$surface2: #585b70;$surface1: #45475a;$surface0: #313244;$base: #1e1e2e;$mantle: #181825;$crust: #11111b;$fg: $text;$bg: $base;$bg1: $surface0;$border: #28283d;$shadow: $crust;
.calendar-win {@include window;background-color: $bg;border: 1px solid $border;color: $fg;padding: .2em;}calendar {padding: 5px;:selected {color: $mauve;}.header {color: $subtext1;}.highlight {color: $maroon;font-weight: bold;}.button {color: $sapphire;}:indeterminate {color: $overlay0;}}
# Eww configurationThis configuration aims to provide a fully working shell replacement forcompositors/window managers. Features constantly get added and existing onesget improved.## 🗃️ ComponentsThe same daemon runs multiple windows which interact with each other:### bar### music window### calendar### system info## ❔ Usage### Home ManagerIf you use Home Manager, installing is as simple as adding my flake to yourinputs, passing `inputs` to `extraSpecialArgs` and importing the relevantmodule:```nix{inputs, ...}: {imports = [inputs.fufexan.homeManagerModules.eww-hyprland];programs.eww-hyprland = {enable = true;# default packagepackage = pkgs.eww-wayland;# if you want to change colorscolors = builtins.readFile ./macchiato.scss;# set to true to reload on changeautoReload = false;};}```Make sure to also add the fonts listed below.### Other distrosTo quickly install this config, grab all the files in this directory and putthem in `~/.config/eww`. Then run `eww daemon` and `eww open bar`. Enjoy!Dependencies:- Icon fonts: `material-symbols-outline` (any variation can be used as long as you change the `font-family` property of `.icon`)- Text font: [Jost](https://fonts.google.com/specimen/Jost)- Script deps: everything in `default.nix`'s `dependencies` list.## 🎨 ThemeThe theme colors can be changed in `css/_colors.scss`. Currently the theme usedis [Catppuccin Mocha](https://github.com/catppuccin/catppuccin).
}: {
}: let# TODO: Move to hyprland moduleewwDeps = with pkgs; [bashbcblueberrybluezcoreutilsdbusdunstfindutilsgawkgnusedgojqimagemagickjaqlightnetworkmanagerpavucontrolprocpspulseaudioripgrepsocatudevupowerutil-linuxwgetwireplumberwlogout];# TODO: Move to desktop modulebwDeps = with pkgs; [wtypepinentry.cursesrbwrofi-rbw];in {
interactiveShellInit = lib.optionalString pkgs.stdenv.isDarwin ''gpgconf --launch gpg-agentset -gx GPG_TTY (tty)set -gx SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket)
interactiveShellInit = letgpgAgentInit = lib.optionalString pkgs.stdenv.isDarwin ''# Initialize GPG agentgpgconf --launch gpg-agentset -gx GPG_TTY (tty)set -gx SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket)'';in ''# Initialize hooks__cd_hook > /dev/null${gpgAgentInit}
Rough roadmap:- [x] Basic setup with ease of adding new hosts- [ ] Modularize the codebase- [ ] Make it possible to update user configuration without root access, even on machines which use NixOS Home Manager module- [ ] Make the theme consistent throughout the system- [ ] Hopefully make it so that others can use some parts of this config without having to copy or fork it :)
Rough roadmap (☑️ - Done, ☒ - In progress, ☐ - TODO):- ☑️ Basic setup with ease of adding new hosts- ☒ Modularize the codebase- ☐ Make it possible to update user configuration without root access, even on machines which use NixOS Home Manager module- ☐ Make the theme consistent throughout the system- ☐ Hopefully make it so that others can use some parts of this config without having to copy or fork it :)
- `wsl` - Obsolete, configuration for when I used Nix on WSL- `virtualBox` - Obsolete, VirtualBox config I tried before installing NixOS
- `hijiri` - (Currently) My main laptop and development machine. At some point will be split into -macos and -linux variants. (When Asahi gets more mature)- `miyagi` - My computer station at work.## CreditsEww config for `miyagi` is temporarily borrowed from https://github.com/fufexan/dotfiles. At some point it'll just be heavily inspired instead.