Skip to content

Commit

Permalink
WIP: Volume mixer widget
Browse files Browse the repository at this point in the history
  • Loading branch information
kajusnau committed Dec 13, 2024
1 parent 6ac9d7e commit 4bea169
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 64 deletions.
192 changes: 129 additions & 63 deletions modules/desktop/graphics/ewwbar.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ let
};
inherit (config.ghaf.services.audio) pulseaudioTcpControlPort;

iconThemeBase = "/run/current-system/sw/share/icons/${
if cfg.gtk.colorScheme == "prefer-dark" then "${cfg.gtk.iconTheme}-Dark" else cfg.gtk.iconTheme
}";

launcher-icon = "${pkgs.ghaf-artwork}/icons/launcher.svg";

battery-0-icon = "${pkgs.ghaf-artwork}/icons/battery-0.svg";
Expand Down Expand Up @@ -50,8 +54,7 @@ let
lock-icon = "${pkgs.ghaf-artwork}/icons/lock.svg";

logout-icon = "${pkgs.ghaf-artwork}/icons/logout.svg";

arrow-right-icon = "${pkgs.ghaf-artwork}/icons/arrow-right.svg";
arrow-right-icon = "${iconThemeBase}/24x24/actions/adjustlevels.svg";

# Called by eww.yuck for updates and reloads
ewwCmd = "${pkgs.eww}/bin/eww -c /etc/eww";
Expand Down Expand Up @@ -282,28 +285,37 @@ let
pkgs.gawk
pkgs.pulseaudio
pkgs.pamixer
pkgs.gnused
pkgs.jq
];
bashOptions = [ ];
text = ''
export PULSE_SERVER=audio-vm:${toString pulseaudioTcpControlPort}
icon() {
if [[ "$2" == "true" || "$1" -eq 0 ]]; then
echo "${volume-0-icon}"
elif [ "$1" -lt 25 ]; then
echo "${volume-1-icon}"
elif [ "$1" -lt 75 ]; then
echo "${volume-2-icon}"
else
echo "${volume-3-icon}"
fi
}
get() {
volume=$(pamixer --get-volume)
muted=$(pamixer --get-mute)
icon=$(icon "$volume" "$muted")
echo "{ \"level\": \"$volume\", \"muted\": \"$muted\", \"icon\": \"$icon\" }"
volume=$(pamixer --get-volume)
muted=$(pamixer --get-mute)
sink_inputs_json=$(pactl -f json list sink-inputs | jq -c '
map({
level: (.volume."front-left".value_percent // "0" | sub("%$"; "")),
muted: (.mute // "false"),
name: (.properties."application.name" // ""),
icon_name: (.properties."application.icon_name" // ""),
id: (.index // "-1")
})
' || echo "[]")
# Output the final JSON
jq -c --unbuffered -n --argjson sinkInputs "$sink_inputs_json" --arg level "$volume" --arg muted "$muted" '
{
system: {
level: $level,
muted: $muted
},
sinkInputs: $sinkInputs
}
'
}
listen() {
Expand Down Expand Up @@ -439,8 +451,8 @@ in
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defpoll keyboard_layout :interval "5s" "${pkgs.xorg.setxkbmap}/bin/setxkbmap -query | ${pkgs.gawk}/bin/awk '/layout/{print $2}' | tr a-z A-Z")
(defpoll battery :interval "5s" :initial "{}" "${eww-bat}/bin/eww-bat get")
(deflisten brightness "${eww-brightness}/bin/eww-brightness listen")
(deflisten volume "${eww-volume}/bin/eww-volume listen")
(deflisten brightness :initial "{}" "${eww-brightness}/bin/eww-brightness listen")
(deflisten volume :initial "{}" "${eww-volume}/bin/eww-volume listen")
(deflisten workspace :initial "1" "${ghaf-workspace}/bin/ghaf-workspace subscribe")
(defvar calendar_day "date '+%d'")
Expand All @@ -451,7 +463,8 @@ in
(defvar brightness-popup-visible "false")
(defvar workspace-popup-visible "false")
(defvar workspaces-visible "false")
;; (defpoll bluetooth :interval "3s" :initial "{}" "${pkgs.bt-launcher}/bin/bt-launcher status")
(defvar volume-mixer-visible "false")
(defvar mixer-sliders "")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Widgets ;;
Expand All @@ -464,7 +477,7 @@ in
:style "background-image: url(\"${launcher-icon}\")")))
;; Generic slider widget ;;
(defwidget sys_slider [?header icon ?settings-icon level ?onchange ?settings-onclick ?icon-onclick ?class ?font-icon ?min]
(defwidget sys_slider [?header ?icon ?app_icon ?settings-icon level ?onchange ?settings-onclick ?icon-onclick ?class ?font-icon ?min]
(box :orientation "v"
:class "qs-slider"
:spacing 10
Expand All @@ -483,9 +496,14 @@ in
:onclick icon-onclick
:hexpand false
:class "icon_settings"
(box :class "icon"
:hexpand false
:style "background-image: url(\"''${icon}\")"))
(overlay
(box :class "icon"
:hexpand false
:style "background-image: url(\"''${icon}\"); opacity: ''${app_icon != "" ? "0" : "1"}")
(box :class "icon"
:hexpand false
:style "background-image: url(\"''${app_icon}\"); opacity: ''${level == 0 || level == min ? "0.5" : "1"}")
))
(label :class "icon" :visible {font-icon != "" ? "true" : "false"} :text font-icon)
(eventbox
:valign "CENTER"
Expand All @@ -496,16 +514,18 @@ in
:orientation "h"
:halign "fill"
:value level
:round-digits 0
:onchange onchange
:max 101
:max 100
:min { min ?: 0 }))
(eventbox
:visible { settings-onclick != "" && settings-onclick != "null" ? "true" : "false" }
:onclick settings-onclick
:class "settings"
(box :class "icon"
:hexpand false
:style "background-image: url(\"''${settings-icon}\")")))))
:style "background-image: url(\"''${settings-icon}\")")))
(children)))
(defwidget sys_sliders []
(box
Expand All @@ -515,17 +535,51 @@ in
:space-evenly false
(sys_slider
:header "Volume"
:icon {volume.icon}
:icon { volume.system.muted == "true" || volume.system.level == 0 ? "${volume-0-icon}" :
volume.system.level <= 25 ? "${volume-1-icon}" :
volume.system.level <= 75 ? "${volume-2-icon}" : "${volume-3-icon}" }
:icon-onclick "${eww-volume}/bin/eww-volume mute &"
:settings-icon "${arrow-right-icon}"
:level { volume.muted == "true" ? "0" : volume.level }
:onchange "PULSE_SERVER=audio-vm:${toString pulseaudioTcpControlPort} ${pkgs.pamixer}/bin/pamixer --unmute --set-volume {} &")
:settings-onclick {volume-mixer-visible == "false" ? "''${EWW_CMD} update volume-mixer-visible=true &" : "''${EWW_CMD} update volume-mixer-visible=false &"}
:level { volume.system.muted == "true" ? "0" : volume.system.level }
:onchange "PULSE_SERVER=audio-vm:${toString pulseaudioTcpControlPort} ${pkgs.pamixer}/bin/pamixer --unmute --set-volume {} &"
(revealer
:transition "slidedown"
:duration "250ms"
:reveal volume-mixer-visible
(box :orientation "v"
(label :text "No audio streams" :visible {arraylength(volume.sinkInputs) == 0})
(volume_mixer)
)))
(sys_slider
:header "Brightness"
:level {brightness.screen.level}
:icon {brightness.icon}
:min "5"
:onchange "${eww-brightness}/bin/eww-brightness set_screen {} &")))
:onchange "${eww-brightness}/bin/eww-brightness set_screen {} &")
)
)
(defwidget volume_mixer []
(scroll
:hscroll "false"
:vscroll "true"
:height { 50 * min(3,arraylength(volume.sinkInputs)) }
(box :orientation "v" :space-evenly false
(for entry in {volume.sinkInputs}
(sys_slider
:header {entry.name}
:level {entry.muted == "true" ? "0" : entry.level}
:app_icon {entry.icon_name != "" ? "${iconThemeBase}/24x24/apps/''${entry.icon_name}.svg" : ""}
:icon { entry.muted == "true" || entry.level == 0 ? "${volume-0-icon}" :
entry.level <= 25 ? "${volume-1-icon}" :
entry.level <= 75 ? "${volume-2-icon}" : "${volume-3-icon}" }
:onchange "${pkgs.pulseaudio}/bin/pactl -s audio-vm:${toString pulseaudioTcpControlPort} set-sink-input-volume ''${entry.id} {}% & ${pkgs.pulseaudio}/bin/pactl -s audio-vm:${toString pulseaudioTcpControlPort} set-sink-input-mute ''${entry.id} 0 &"
:icon-onclick "${pkgs.pulseaudio}/bin/pactl -s audio-vm:${toString pulseaudioTcpControlPort} set-sink-input-mute ''${entry.id} toggle &")
)
)
)
)
;; Generic Widget Buttons For Quick Settings ;;
(defwidget widget_button [icon ?title ?header ?subtitle ?onclick ?font-icon ?class]
Expand Down Expand Up @@ -611,7 +665,7 @@ in
(widget_button
:icon "${bluetooth-1-icon}"
:header "Bluetooth"
:onclick "''${EWW_CMD} close quick-settings closer & ${pkgs.bt-launcher}/bin/bt-launcher &")
:onclick "''${EWW_CMD} close quick-settings closer & ''${EWW_CMD} update volume-mixer-visible=false & ${pkgs.bt-launcher}/bin/bt-launcher &")
(box
:hexpand true
:vexpand true
Expand All @@ -635,37 +689,42 @@ in
(widget_button
:icon "${settings-icon}"
:header "Settings"
:onclick "''${EWW_CMD} close quick-settings closer & ${pkgs.ctrl-panel}/bin/ctrl-panel >/dev/null &")))
:onclick "''${EWW_CMD} close quick-settings closer & ''${EWW_CMD} update volume-mixer-visible=false & ${pkgs.ctrl-panel}/bin/ctrl-panel >/dev/null &")))
''}
;; Reusable Widgets ;;
(defwidget wrapper [?space-evenly ?spacing ?orientation]
(box
:class "wrapper_widget"
:space-evenly {space-evenly != "" ? space-evenly : "false"}
:spacing {spacing != "" ? spacing : "10"}
:orientation {orientation != "" ? orientation : "v"}
(children)))
(defwidget desktop-widget [?space-evenly ?orientation]
(box
:class "floating-widget"
:space-evenly {space-evenly != "" ? space-evenly : "false"}
:orientation {orientation != "" ? orientation : "v"}
(children)))
;; Quick Settings Widget ;;
(defwidget quick-settings-widget []
(box :class "floating-widget"
:orientation "v"
:space-evenly false
(box
:class "wrapper_widget"
:space-evenly false
:spacing 10
:orientation "v"
(desktop-widget
(wrapper
(etc)
(sys_sliders))))
;; Power Menu Widget ;;
(defwidget power-menu-widget []
(box :class "floating-widget"
:orientation "v"
:space-evenly false
(box
:class "wrapper_widget"
:space-evenly false
:orientation "v"
(desktop-widget
(wrapper
(power_menu))))
;; Brightness Popup Widget ;;
(defwidget brightness-popup []
(revealer :transition "crossfade" :duration "200ms" :reveal brightness-popup-visible :active false
(box :class "wrapper_widget"
(wrapper
(box :class "hotkey"
(sys_slider
:valign "center"
Expand All @@ -675,25 +734,27 @@ in
;; Volume Popup Widget ;;
(defwidget volume-popup []
(revealer :transition "crossfade" :duration "200ms" :reveal volume-popup-visible :active false
(box :class "wrapper_widget"
(wrapper
(box :class "hotkey"
(sys_slider
:valign "center"
:icon {volume.icon}
:level {volume.level})))))
:icon { volume.system.muted == "true" || volume.system.level == 0 ? "${volume-0-icon}" :
volume.system.level <= 25 ? "${volume-1-icon}" :
volume.system.level <= 75 ? "${volume-2-icon}" : "${volume-3-icon}" }
:level {volume.system.level})))))
;; Workspace Popup Widget ;;
(defwidget workspace-popup []
(revealer :transition "crossfade" :duration "200ms" :reveal workspace-popup-visible :active false
(box :class "wrapper_widget"
(wrapper
(box :class "hotkey"
(label :text "Desktop ''${workspace}")))))
;; Quick Settings Button ;;
(defwidget quick-settings-button [screen bat-icon vol-icon bright-icon]
(button :class "icon_button"
:onclick "if ''${EWW_CMD} active-windows | grep -q 'quick-settings'; then \
''${EWW_CMD} close closer quick-settings & \
''${EWW_CMD} close closer quick-settings & ''${EWW_CMD} update volume-mixer-visible=false & \
else \
''${EWW_CMD} close power-menu calendar & \
''${EWW_CMD} open --screen \"''${screen}\" closer --arg window=\"quick-settings\" && ''${EWW_CMD} open --screen \"''${screen}\" quick-settings; \
Expand Down Expand Up @@ -721,6 +782,7 @@ in
''${EWW_CMD} close closer power-menu & \
else \
''${EWW_CMD} close quick-settings calendar & \
''${EWW_CMD} update volume-mixer-visible=false & \
''${EWW_CMD} open --screen \"''${screen}\" closer --arg window=\"power-menu\" && ''${EWW_CMD} open --screen \"''${screen}\" power-menu; \
fi &"
(box :class "icon"
Expand All @@ -740,7 +802,9 @@ in
:class "control"
(quick-settings-button :screen screen
:bright-icon {brightness.icon}
:vol-icon {volume.icon}
:vol-icon { volume.system.muted == "true" || volume.system.level == 0 ? "${volume-0-icon}" :
volume.system.level <= 25 ? "${volume-1-icon}" :
volume.system.level <= 75 ? "${volume-2-icon}" : "${volume-3-icon}" }
:bat-icon {battery.icon})))
;; Divider ;;
Expand Down Expand Up @@ -773,14 +837,15 @@ in
''${EWW_CMD} close closer calendar & \
else \
''${EWW_CMD} close quick-settings power-menu & \
''${EWW_CMD} update volume-mixer-visible=false & \
''${EWW_CMD} open --screen \"''${screen}\" closer --arg window=\"calendar\" && ''${EWW_CMD} open --screen \"''${screen}\" calendar; \
fi &"
:class "icon_button date" "''${formattime(EWW_TIME, "%a %b %-d")}"))
;; Calendar ;;
(defwidget cal []
(box :class "floating-widget"
(box :class "wrapper_widget"
(desktop-widget
(wrapper
(calendar :class "cal"
:show-week-numbers false
:day calendar_day
Expand Down Expand Up @@ -870,7 +935,7 @@ in
:geometry (geometry
:x "0px"
:y "0px"
:height "36px"
:height "30px"
:width "100%"
:anchor "top center")
:focusable "false"
Expand Down Expand Up @@ -954,9 +1019,10 @@ in
$bg-secondary: #2B2B2B;
$text-base: #FFFFFF;
$text-disabled: #9c9c9c;
$text-success: #5AC379;
$text-success: rgba(90, 195, 121, 1);
$icon-subdued: #3D3D3D;
$stroke-success: #5AC379;
$stroke-success: rgba(90, 195, 121, 1);
$stroke-success-muted: rgba(90, 195, 121, 0.75);
$font-bold: 600;
@mixin unset($rec: false) {
Expand Down Expand Up @@ -1041,7 +1107,7 @@ in
}
}
@mixin slider($slider-width: 225px, $slider-height: 2px, $thumb: true, $thumb-width: 1em, $focusable: true, $radius: 7px, $shadows: true, $trough-bg: $widget-hover) {
@mixin slider($slider-width: 225px, $slider-height: 2px, $thumb: true, $thumb-width: 1em, $focusable: true, $radius: 7px, $shadows: true, $trough-bg: $widget-hover, $trough-fg: $stroke-success) {
trough {
border-radius: $radius;
border: 0;
Expand All @@ -1052,7 +1118,7 @@ in
highlight,
progress {
background-color: $stroke-success;
background-color: $trough-fg;
border-radius: $radius;
}
}
Expand Down Expand Up @@ -1197,7 +1263,7 @@ in
.floating-widget { @include floating_widget; }
.qs-slider {
.qs-slider {
@include unset($rec: true);
@include sys-sliders;
@include qs-widget($min-height: 0px);
Expand Down
Loading

0 comments on commit 4bea169

Please sign in to comment.