feat: update volume widget and visual
This commit is contained in:
+12
-2
@@ -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
@@ -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
@@ -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()
|
||||
Reference in New Issue
Block a user