elkowar / eww

ElKowars wacky widgets
https://elkowar.github.io/eww
MIT License
9.3k stars 382 forks source link

[BUG] No initial values for dynamic vars #765

Open charlesrocket opened 1 year ago

charlesrocket commented 1 year ago

Checklist before submitting an issue

Description of the bug

Can not get initial values from any defpoll/deflisten variables. Everything works as expected and no errors observed besides missing at the start window title and failed validations in logs:

error: Failed to turn `` into a value of type json-value
    ┌─ /usr/home/charlie/.config/eww/eww.yuck:103:23
    │
103 │     (metric :label "${battery_info.stat == "ac" ? "" : ""}"
    │                       ────────────

error: Failed to turn `` into a value of type json-value
    ┌─ /usr/home/charlie/.config/eww/eww.yuck:105:29
    │
105 │             :label-class "${battery_info.message == "critical" ?
    │                             ────────────

error: Failed to turn `` into a value of type json-value
    ┌─ /usr/home/charlie/.config/eww/eww.yuck:109:23
    │
109 │             :tooltip {battery_info.time}
    │                       ────────────

error: Failed to turn `` into a value of type json-value
    ┌─ /usr/home/charlie/.config/eww/eww.yuck:110:23
    │
110 │             :visible {battery_info.source == "battery" ? true : false}

Not sure what is wrong, definitions are very straightforward

(deflisten workspaces :initial
  "[]" "sh ~/.config/eww/scripts/get-workspaces")
(deflisten current_workspace :initial
  "1" "sh ~/.config/eww/scripts/get-active-workspace")
(deflisten window :initial
  "..." "sh ~/.config/eww/scripts/get-window-title")

(defpoll network_info :interval "5s" "perl ~/.config/eww/scripts/get-network")
(defpoll battery_info :interval "5s" "perl ~/.config/eww/scripts/get-battery")
(defpoll time :interval "10s" "date '+%H:%M'")  
(defpoll date :interval "1m" "date '+ %d %B %Y'")

Full config:

(defwindow bar
  :monitor 0
  :namespace "eww-bar"
  :exclusive true
  :geometry (geometry :x "0%"
                      :y "0%"
                      :width "100%"
                      :height "20px"
                      :anchor "top center")
  (bar))

(deflisten workspaces :initial
  "[]" "sh ~/.config/eww/scripts/get-workspaces")
(deflisten current_workspace :initial
  "1" "sh ~/.config/eww/scripts/get-active-workspace")
(deflisten window :initial
  "..." "sh ~/.config/eww/scripts/get-window-title")

(defpoll network_info :interval "5s" "perl ~/.config/eww/scripts/get-network")
(defpoll battery_info :interval "5s" "perl ~/.config/eww/scripts/get-battery")
(defpoll time :interval "10s" "date '+%H:%M'")  
(defpoll date :interval "1m" "date '+ %d %B %Y'")

(defvar clock_rev false)

(defwidget bar []
  (box :orientation "h"
       :class "main-bar"
    (left)
    (center)
    (right)))

(defwidget left []
  (box :class "left-bar"
       :halign "start"
       :valign "fill"
    (workspaces)))

(defwidget center []
  (box :class "center-bar"
       :halign "center"
       :valign "fill"
    (window_w)))

(defwidget right []
  (box :halign "end"
       :space-evenly false
       :class "right-bar"
    (stats)
    (separator)
    (network)
    (separator)
    (clock)))

(defwidget window_w []
  (box :halign "center"
    (label :text "${window}"
           :limit-width 65)
  ))

(defwidget clock []
  (eventbox :onhover "${EWW_CMD} update clock_rev=true"
            :onhoverlost "${EWW_CMD} update clock_rev=false"
    (box :space-evenly false
         :class "clock"
         :spacing 10
      (label :text time)
        (revealer :transition "slideleft"
                  :reveal clock_rev
                  :duration "600ms"
          (date)))))

(defwidget date []
  (box
    (label :text date)))

(defwidget stats []
  (box :class "stats"
       :orientation "h"
       :halign "end"
    (metric :label ""
            :label-visible true
            :label-class "stats-cpu"
            :value {EWW_CPU.avg}
            :tooltip "Avg. ${round(EWW_CPU.avg, 3)}"
            :visible true
            :onchange "")
    (metric :label ""
            :label-visible true
            :label-class "stats-ram"
            :value {EWW_RAM.used_mem_perc}
            :tooltip "${round(EWW_RAM.used_mem_perc, 0)}% used"
            :visible true
            :onchange "")
    (metric :label ""
            :label-class "stats-disk"
            :label-visible true
            :value
              {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)}
            :tooltip "${round(EWW_DISK['/'].used_perc, 0)}% used"
            :visible true
            :onchange "")
    (metric :label "${battery_info.stat == "ac" ? "" : ""}"
            :label-visible {battery_info.source == "battery" ? true : false}
            :label-class "${battery_info.message == "critical" ?
              "stats-batt-low" : ""} ${battery_info.message == "charged" ?
              "stats-batt-charged" : ""}"
            :value {battery_info.percentage}
            :tooltip {battery_info.time}
            :visible {battery_info.source == "battery" ? true : false}
            :onchange "")))

(defwidget workspaces []
  (box :space-evenly false
       :spacing 5
       :class "workspaces"
    (label :text "${workspaces}${current_workspace}"
           :visible false)
    (for workspace in workspaces
      (eventbox :onclick "hyprctl dispatch workspace ${workspace.id}"
        (box :class "workspace-entry ${workspace.id == current_workspace ?
            "workspace-current" : "workspace-inactive"} ${workspace.windows > 0 ?
            "workspace-occupied" : "workspace-empty"}"
          (label :text "${workspace.name}")
          )
        )
      )
    )
  )

(defwidget network []
  (box :class "network"
       :spacing 10
    (label :text "${network_info.vpn == "active" ? "" : ""}"
           :class "${network_info.status == "online" ?
              "network-online" : "network-offline"}")
    (label :text "${network_info.interface}")))

(defwidget metric [
  label label-class value tooltip visible label-visible onchange]
  (box :orientation "h"
       :class "metric"
       :space-evenly true
    (box :visible label-visible
         :class label-class label)
    (scale :min 0
           :max 101
           :orientation "v"
           :flipped true
           :active {onchange != ""}
           :value value
           :tooltip tooltip
           :visible visible
           :onchange onchange)))

(defwidget separator []
  (box
    (label :text "|"
           :class "separator")))

I thought this might be due invalid widget ordering or something with metric but I can not find anything in docs regarding correct ordering/declarations. Basic "window title" nulls confirmed that this is not a module definition issue but something more general.

Reproducing the issue

https://github.com/charlesrocket/dotfiles/tree/5e48cac02e0471a72f727ca4ada2d59d3810e2d9/.config/eww

Expected behaviour

Initial variables present

Additional context

OS:        FreeBSD 13.2-RELEASE
KERNEL:    GENERIC 1302001
SHELL:     zsh
DE:        Hyprland
Name           : eww-wayland
Version        : 0.4.0_8
viandoxdev commented 1 year ago

Pretty sure you just want to put a :initial on these

charlesrocket commented 1 year ago

@viandoxdev :initial "defaults to poll at startup" so it should still work, just slower. Also listening vars do have initial values hardcoded but window title is still empty. Appending {} initial to polls does fixes JSON error in logs but widget still shows nothing and state is inconclusive. The rest of errors are old:

error: Failed to turn `` into a value of type bool
    ┌─ /usr/home/charlie/.config/eww/eww.yuck:147:21
    │
147 │            :visible visible
    │                     ─────── `` is not of type `bool`

Debug shows valid variables so it feels like default poll at start is ignored.

UPD: I figured out the listener, forgot to catch the state. But still can't get polls to use start values.

charlesrocket commented 1 year ago

Not sure if this is related, but every now and then eww would deploy a duplicated window at the start that can't be closed natively.

charlesrocket commented 1 year ago

Tried to resolve some issues with initials as per @viandoxdev suggestion but widgets remain hasty, apparently - only this hack works:

(defwidget window []
  (box :halign "center"
    (label :text {window_title == "" ? "" :
                  window_title == "null" ? "" : window_title }
           :limit-width 65)
  ))