feat: update volume widget and visual

This commit is contained in:
2026-04-07 22:04:55 +04:00
parent 54f98286a6
commit c2ae3d05be
3 changed files with 48 additions and 37 deletions
+12 -2
View File
@@ -187,14 +187,24 @@ separator {
.volume-pill {
@extend .capsule;
.icon, .stat-label { transition: color $t-norm ease-in-out; }
.icon { margin-right: 14px; }
.slide-wrapper { transition: all $t-fast ease-in-out; }
&.muted {
border-color: #444;
.icon, .stat-label { color: $muted-gray; }
scale slider { background-color: $muted-gray; }
scale trough highlight { background-color: #444; }
scale slider {
background-color: $muted-gray;
transition: background-color $t-norm ease-in-out;
}
scale trough highlight {
background-color: #444;
transition: background-color $t-norm ease-in-out;
}
.slide-wrapper {
border-color: #444;
transition: all $t-slow ease-in-out;
+14 -8
View File
@@ -13,7 +13,7 @@
;; слушатели
(deflisten ws_data :initial "{}" "python3 $HOME/.config/eww/scripts/workspaces.py")
(deflisten volume :initial "0" "python3 $HOME/.config/eww/scripts/volume.py")
(deflisten volume :initial '{"volume": 0, "muted": false}' "python3 -u $HOME/.config/eww/scripts/volume.py")
(deflisten layout :initial "EN" "socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | stdbuf -oL awk -F'>>' '/activelayout/ {split(\$2, a, \",\"); print toupper(substr(a[2], 1, 2))}'")
(deflisten tray_count :initial "0" "python3 $HOME/.config/eww/scripts/tray_monitor.py")
(deflisten kb_leds :initial '{"caps":"0","num":"0"}' "python3 $HOME/.config/eww/scripts/kb_leds.py")
@@ -73,15 +73,21 @@
;; звук
(defwidget volumewidget [reveal_state reveal_var]
(eventbox :cursor "pointer" :onclick "eww update ${reveal_var}=${!reveal_state}"
(box :class "capsule volume-pill ${reveal_state ? 'active' : ''} ${volume == 0 || volume == '' ? 'muted' : ''}"
(eventbox :cursor "pointer"
:onclick "eww update ${reveal_var}=${!reveal_state}"
:onrightclick "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
:onscroll "echo {} | sed -e 's/up/5%+/g' -e 's/down/5%-/g' | xargs wpctl set-volume -l 1.35 @DEFAULT_AUDIO_SINK@"
(box :class "capsule volume-pill ${reveal_state ? 'active' : ''} ${volume.muted || volume.volume == 0 || volume.volume == '0' ? 'muted' : ''}"
:space-evenly false
(label :class "icon" :text {volume == 0 || volume == "" ? "" : (volume < 50 ? "" : "")})
(label :class "stat-label" :text "${volume}%" :width 38)
(revealer :reveal reveal_state :transition "slideleft"
(label :class "icon"
:text {volume.muted || volume.volume == 0 || volume.volume == "0" ? "" : (volume.volume < 50 ? "" : "")})
(label :class "stat-label"
:text "${volume.volume}%" :width 38)
(revealer :reveal reveal_state
:transition "slideleft"
(box :class "slide-wrapper"
(scale :class "vol-bar" :min 0 :max 101 :value {volume ?: 0}
:onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%"))))))
(scale :class "vol-bar" :min 0 :max 101 :value {volume.volume}
:onchange "wpctl set-volume @DEFAULT_AUDIO_SINK@ {}%"))))))
;; часы
(defwidget timewidget [reveal_state reveal_var]
+22 -27
View File
@@ -1,42 +1,37 @@
import subprocess
import sys
import os
import signal
import json
import re
class VolumeMonitor:
def __init__(self):
# отдаём текущую громкость при старте
self.push_update()
def get_vol(self):
# достаём цифры из pactl
def get_vol_info(self):
try:
raw = subprocess.check_output(["pactl", "get-sink-volume", "@DEFAULT_SINK@"], stderr=subprocess.DEVNULL).decode()
if "/" in raw:
# забираем канал и чистим от процентов
return raw.split("/")[1].strip().replace("%", "")
except:
return "0"
return "0"
# Получаем громкость + состояние
raw = subprocess.check_output(["wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@"]).decode().strip()
# Получаем громкость
match = re.search(r"(\d\.\d+)", raw)
vol_val = float(match.group(1)) if match else 0.0
percent = int(vol_val * 100)
# Проверяем наличие метки muted
is_muted = "[MUTED]" in raw
return json.dumps({"volume": percent, "muted": is_muted})
except Exception:
return json.dumps({"volume": 0, "muted": False})
def push_update(self):
# отдаём данные в stdout для eww
vol = self.get_vol()
sys.stdout.write(f"{vol}\n")
sys.stdout.write(f"{self.get_vol_info()}\n")
sys.stdout.flush()
def run(self):
# подписываемся на события аудио-сервера
self.push_update()
proc = subprocess.Popen(["pactl", "subscribe"], stdout=subprocess.PIPE, text=True)
try:
for line in proc.stdout:
# если изменился основной выход
if "sink" in line:
self.push_update()
except KeyboardInterrupt:
proc.terminate()
sys.exit(0)
for line in proc.stdout:
if "sink" in line or "server" in line:
self.push_update()
if __name__ == "__main__":
VolumeMonitor().run()