Switch to eww for status bar

This commit is contained in:
Kiana Sheibani 2024-05-11 19:17:30 -04:00
parent f4c7c3e1e2
commit 106a9f4b38
15 changed files with 704 additions and 10 deletions

View file

@ -64,10 +64,8 @@ in
fonts = {
enableDefaultPackages = true;
packages = with pkgs; [
# Monospace
victor-mono
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
jetbrains-mono
(nerdfonts.override {
fonts = [
@ -78,7 +76,18 @@ in
})
font-awesome
emacs-all-the-icons-fonts
# Regular
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
source-sans-pro
# Display
quicksand
# Unicode
symbola
];
fontconfig = {

View file

@ -5,9 +5,11 @@
ffmpeg
openssl
jaq
socat
git
wget
libnotify
inotify-tools
ripgrep
unzip
tldr

View file

@ -0,0 +1,247 @@
$background: #1a1626;
$background-alt: #252630;
$background-scale: #414868;
$foreground: #c0caf5;
$foreground-alt: #8189af;
$foreground-light: #343b58;
$disabled: #565f89;
$accent: #f6a8cf;
* {
all: unset;
}
@mixin segment {
background-color: $background-alt;
border-radius: 20px;
margin: 0px 2px;
}
.bar {
background-color: $background;
font-family: "Quicksand Medium";
color: $foreground;
font-size: 13;
padding: 3px 10px;
}
tooltip {
background-color: rgba(0,0,0,0.8);
font-family: "JetBrains Mono";
font-size: 12;
}
.detail {
font-size: 10;
color: $foreground-alt;
}
.bar-sep {
margin: 0px 5px;
color: $background-alt;
font-size: 22;
}
.bar-window {
margin-left: 4px;
.detail {
margin-top: 1px;
}
:not(.detail) {
margin-top: -2px;
margin-left: 1px;
}
}
.bar-time {
@include segment;
font-size: 15;
padding: 0px 10px;
.bar-date {
margin-top: 1px;
font-size: 11;
color: #a9b1d6;
}
}
.bar-music {
@include segment;
padding-left: 3px;
padding-right: 10px;
.progress {
margin-right: 5px;
.back {
color: $background-scale;
}
.front {
color: $accent;
}
}
.symbol.paused {
font-size: 12;
margin-left: 2px;
}
.symbol.playing {
font-size: 15;
margin-top: 1px;
}
.bar-artist {
margin-top: 1px;
margin-bottom: -2px;
}
.bar-title {
margin-bottom: -3px;
}
}
.bar-workspaces {
@include segment;
padding: 3px 5px;
.workspace-button {
padding: 0px 5px;
border-radius: 20px;
color: #51587a;
&.occupied {
background-color: $background-scale;
color: $accent;
}
&.current + box {
padding: 0px 7px;
border-radius: 20px;
background-color: $accent;
color: $foreground-light;
}
&.occupied.previous-occupied {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&.occupied.next-occupied {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}
scale trough {
background-color: $background-scale;
border-radius: 5px;
min-height: 6px;
min-width: 60px;
margin: 0px 5px;
highlight {
border-radius: 5px;
}
}
.bar-scale {
margin: 0px 5px;
.percent {
margin-top: -1px;
margin-left: 3px;
}
}
@mixin scale-color($color) {
color: $color;
scale highlight {
background-color: $color;
}
}
.bar-volume {
@include scale-color(#7dcfff);
&.muted { @include scale-color(#f7768e); }
.symbol {
margin-right: 6px;
font-size: 17;
}
}
.bar-brightness {
@include scale-color(#e0af68);
.symbol {
margin-right: 7px;
font-size: 14;
}
}
.bar-internet {
margin-left: 7px;
margin-right: 10px;
font-family: "JetBrains Mono";
color: #bb9af7;
font-size: 12;
&.disabled {
color: $disabled;
}
.symbol {
font-size: 15;
}
}
.bar-bluetooth {
margin: 0px 5px;
font-size: 15;
color: #7aa2f7;
&.disabled {
color: $disabled;
}
}
.bar-circular {
margin: 0px 4px;
font-size: 15;
.back {
color: $background-scale;
}
&.critical {
color: #f7768e;
}
}
.bar-battery {
color: #8ece6a;
}
.bar-ram {
color: #b4f9f8;
.symbol {
margin-right: 5px;
}
}
.bar-storage {
color: #cfc9c2;
.symbol {
margin-right: 1px;
}
}

View file

@ -0,0 +1,339 @@
;; Window Info
(deflisten window :initial "{}"
"~/.config/eww/scripts/active-window")
(defwidget bar_window []
(box :class "bar-window"
:orientation "v"
:space-evenly false
(label :class "detail"
:halign "start"
:valign "end"
:limit-width 60
:text {window.class ?: "Desktop"})
(label :halign "start"
:valign "end"
:limit-width 55
:text {window.title ?: "Workspace ${current_workspace}"})))
;; Workspaces
(deflisten workspaces :initial "[]"
"~/.config/eww/scripts/get-workspaces")
(deflisten current_workspace :initial "1"
"~/.config/eww/scripts/get-active-workspace")
(defwidget bar_workspace_button [workspace]
(eventbox :onclick "hyprctl dispatch workspace ${workspace.id}"
(overlay
(box :class "segment workspace-button ${workspace.id == current_workspace ? "current" : ""
} ${workspace.windows > 0 ? "occupied" : "empty"
} ${workspace.previous > 0 ? "previous-occupied" : "previous-empty"
} ${workspace.next > 0 ? "next-occupied" : "next-empty"}"
(label :text "${workspace.id}"))
(box :visible {workspace.id == current_workspace}
(label :text "${workspace.id}")))))
(defwidget bar_workspaces []
(eventbox :onscroll "~/.config/eww/scripts/change-active-workspace {} ${current_workspace}"
(box :class "bar-workspaces"
:orientation "h"
:space-evenly true
(for workspace in workspaces
(bar_workspace_button :workspace workspace)))))
;; Time
(defwidget bar_time []
(box :class "bar-time segment"
:orientation "h"
:width 195
:space-evenly false
:spacing 6
(label :halign "start"
:yalign 0.5
:text {formattime(EWW_TIME, "%H:%M:%S")})
(label :class "bar-date"
:halign "end"
:hexpand true
:yalign 0.5
:text {formattime(EWW_TIME, "%A, %Y-%m-%d")})))
;; Playerctl
(deflisten mpris :initial "{}"
"~/.config/eww/scripts/mpris-metadata")
(defwidget bar_music []
(eventbox :onclick "playerctl play-pause"
(box :class "bar-music segment"
:orientation "h"
:width 195
:space-evenly false
(box :class "progress"
(overlay
(circular-progress :class "back"
:value 100
:width 25
:thickness 2
:start-at 75
:clockwise true)
(circular-progress :class "front"
:value {(mpris.position ?: 0) == 0 ||
(mpris.duration ?: 0) == 0 ? 0 :
mpris.position > mpris.duration ? 100 :
mpris.position / mpris.duration * 100}
:width 25
:thickness 2
:start-at 75
:clockwise true)
(label :class "symbol ${mpris.status == "Playing" ? "playing" : "paused"}"
:text {mpris.status == "Playing" ? "󰏤" : ""})))
(box :orientation "v"
:space-evenly false
:visible {(mpris.title ?: "") != "" && (mpris.status ?: "Stopped") != "Stopped"}
(label :class "bar-artist detail"
:halign "start"
:limit-width 30
:text {mpris.artist ?: ""})
(label :halign "bar-title"
:limit-width 25
:text {mpris.title ?: ""})))))
;; Scales (Volume + Brightness)
(defwidget bar_scale [?class reveal_name reveal value symbol onchange ?onclick]
(eventbox :onhover "${EWW_CMD} update ${reveal_name}=true"
:onhoverlost "${EWW_CMD} update ${reveal_name}=false"
(box :class "bar-scale ${class}"
:space-evenly false
(eventbox :onclick onclick
(label :class "symbol"
:text symbol))
(revealer :transition "slideright"
:reveal reveal
:duration "400ms"
(scale :value value
:orientation "h"
:width "100%"
:min 0
:max 101
:onchange onchange))
(label :class "percent"
:width 29
:xalign 0
:text "${value}%"))))
(defvar volume_reveal false)
(deflisten volume :initial "0"
"~/.config/eww/scripts/volume")
(defwidget bar_volume []
(bar_scale :class "bar-volume ${volume.muted ? "muted" : ""}"
:reveal_name "volume_reveal"
:reveal volume_reveal
:value {volume.value}
:symbol {volume.muted ? "󰝟" :
volume.value < 5 ? "󰖁" :
volume.value < 35 ? "󰕿" :
volume.value < 66 ? "󰖀" : "󰕾"}
:onchange "pamixer --set-volume {}"
:onclick "pamixer -t"))
(defvar brightness_reveal false)
(deflisten brightness :initial "0"
"~/.config/eww/scripts/brightness")
(defwidget bar_brightness []
(bar_scale :class "bar-brightness"
:reveal_name "brightness_reveal"
:reveal brightness_reveal
:value brightness
:symbol "󰃠"
:onchange "brightnessctl -e s {}%"))
;; Circular Indicators
(defwidget bar_circular [?class ?critical ?tooltip value symbol]
(box :class "bar-circular ${class} ${(critical ?: false) ? "critical" : ""}"
:orientation "h"
:tooltip tooltip
(overlay
(circular-progress :class "back"
:value 100
:width 25
:thickness 2
:start-at 75
:clockwise true)
(circular-progress :class "front"
:value value
:width 25
:thickness 2
:start-at 75
:clockwise true)
(label :class "symbol"
:text symbol))))
(defwidget bar_battery []
(bar_circular :class "bar-battery"
:critical {EWW_BATTERY["BAT1"].capacity <= 15}
:tooltip "Battery: ${EWW_BATTERY["BAT1"].capacity}%"
:value {EWW_BATTERY["BAT1"].capacity}
:symbol {EWW_BATTERY["BAT1"].status == "Charging" ? "󰂄" : "󰁹"}))
(defwidget bar_ram []
(bar_circular :class "bar-ram"
:critical {EWW_RAM.used_mem_perc >= 95}
:tooltip "RAM: ${round(EWW_RAM.used_mem / 1073741824, 2)
} / ${round(EWW_RAM.total_mem / 1073741824, 2)} GB (${round(EWW_RAM.used_mem_perc, 2)}%)"
:value {EWW_RAM.used_mem_perc}
:symbol ""))
(defwidget bar_storage []
(bar_circular :class "bar-storage"
:tooltip "Storage: ${round(EWW_DISK["/"].used / 1073741824, 2)
} / ${round(EWW_DISK["/"].total / 1073741824, 0)} GB (${round(EWW_DISK["/"].used_perc, 2)}%)"
:value {EWW_DISK["/"].used_perc}
:symbol "󰆼"))
;; Network
(defpoll wifi :interval "2s" :initial "{}"
"~/.config/eww/scripts/network 802-11-wireless")
(defpoll ethernet :interval "2s" :initial "{}"
"~/.config/eww/scripts/network 802-3-ethernet")
(defpoll bluetooth :interval "2s" :initial "{}"
"~/.config/eww/scripts/network bluetooth")
(defvar internet_reveal false)
(defwidget bar_internet []
(box :class "bar-internet ${wifi == "{}" && ethernet == "{}" ? "disabled" : ""}"
:space-evenly false
:tooltip {ethernet != "{}" ? "${ethernet.name} (${ethernet.device}, ${EWW_NET[ethernet.device].up}B up, ${EWW_NET[ethernet.device].down}B down)" :
wifi != "{}" ? "${wifi.name} (${wifi.device}, ${EWW_NET[wifi.device].NET_UP}B up, ${EWW_NET[wifi.device].NET_DOWN}B down)" : ""}
(label :class "symbol"
:text {wifi != "{}" ? "󰤨" : ethernet != "{}" ? "󰈁" : "󰤮"})))
(defwidget bar_bluetooth []
(box :class "bar-bluetooth ${bluetooth == "{}" ? "disabled" : ""}"
(label :limit-width 15
:text {bluetooth != "{}" ? "󰂯" : "󰂲"})))
;; Separator
(defwidget bar_sep []
(box :class "bar-sep"
:hexpand false
:vexpand false
(label :text "|")))
;; Bar Layout
(defwidget bar_left_edge []
(box :orientation "h"
:space-evenly false
:halign "start"
:hexpand true
(bar_window)))
(defwidget bar_left_wing []
(box :orientation "h"
:space-evenly false
:halign "end"
:hexpand true
(bar_time)))
(defwidget bar_center []
(bar_workspaces))
(defwidget bar_right_wing []
(box :orientation "h"
:space-evenly false
:hexpand true
(bar_music)))
(defwidget laptop_bar_right_edge []
(box :orientation "h"
:space-evenly false
:halign "end"
:hexpand true
(bar_volume)
(bar_brightness)
(bar_sep)
(bar_bluetooth)
(bar_internet)
(bar_sep)
(bar_storage)
(bar_ram)
(bar_battery)))
(defwidget laptop_bar_layout []
(centerbox :class "bar"
:orientation "h"
(box :orientation "h"
:space-evenly false
:hexpand true
(bar_left_edge)
(bar_left_wing))
(bar_center)
(box :orientation "h"
:space-evenly false
(bar_right_wing)
(laptop_bar_right_edge))))
(defwidget desktop_bar_right_edge []
(box :orientation "h"
:space-evenly false
:halign "end"
:hexpand true
(bar_volume)
(bar_sep)
(bar_bluetooth)
(bar_internet)
(bar_sep)
(bar_storage)
(bar_ram)))
(defwidget desktop_bar_layout []
(centerbox :class "bar"
:orientation "h"
(box :orientation "h"
:space-evenly false
:hexpand true
(bar_left_edge)
(bar_left_wing))
(bar_center)
(box :orientation "h"
:space-evenly false
(bar_right_wing)
(laptop_bar_right_edge))))
(defwindow laptop_bar
:geometry (geometry :width "100%"
:height "3%"
:anchor "top center")
:namespace "eww-bar"
:stacking "fg"
:exclusive true
:focusable false
(laptop_bar_layout))
(defwindow desktop_bar
:geometry (geometry :width "100%"
:height "3%"
:anchor "top center")
:namespace "eww-bar"
:stacking "fg"
:exclusive true
:focusable false
(desktop_bar_layout))

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
hyprctl activewindow -j | jaq -c .
socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - |
stdbuf -o0 grep -ose '^activewindow>>' | while read -r line; do
hyprctl activewindow -j | jaq -c .
done

View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
brightnessctl -me | cut -d, -f4 | tr -d '%'
device=$(brightnessctl -m | head -n 1 | cut -d, -f1)
while true; do
inotifywait /sys/class/backlight/"$device"/brightness &>/dev/null
brightnessctl -me | cut -d, -f4 | tr -d '%'
done

View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
direction=$1
current=$2
min=1
max=10
function clamp {
if test $1 -lt $min; then
echo $min
elif test $1 -gt $max; then
echo $max
else
echo $1
fi
}
if test "$direction" = "down"
then
target=$(clamp $(($current+1)))
echo "jumping to $target"
hyprctl dispatch workspace $target
elif test "$direction" = "up"
then
target=$(clamp $(($current-1)))
echo "jumping to $target"
hyprctl dispatch workspace $target
fi

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
hyprctl monitors -j | jaq '.[] | select(.focused) | .activeWorkspace.id'
socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - |
stdbuf -o0 awk -F '>>|,' -e '/^workspace>>/ {print $2}' -e '/^focusedmon>>/ {print $3}'

View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
workspaces() {
hyprctl workspaces -j | jaq -c 'map({key: .id | tostring, value: .windows}) | from_entries
| . as $windows | [range(1;11) | {id: tostring, windows: $windows[tostring] // 0,
previous: $windows[.-1|tostring] // 0, next: $windows[.+1|tostring] // 0 }]'
}
workspaces
socat -u UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do
workspaces
done

View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
playerctl metadata --follow --format \
'{"playerName": "{{ playerName }}",'\
'"status": "{{ status }}",'\
'"artist": "{{ artist }}",'\
'"title": "{{ title }}",'\
'"album": "{{ album }}",'\
'"position": "{{ position }}",'\
'"position_d": "{{ duration(position) }}",'\
'"duration": "{{ mpris:length }}",'\
'"duration_d": "{{ duration(mpris:length) }}"}'

View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
nmcli -t c show --active | awk -F ':' -e \
'// { if ($3 == "'$1'") {
print "{\"name\":\""$1"\",\"device\":\""$4"\"}";
found = 1;
exit;
}}
END { if (!found) print "{}" }'

View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
volume() {
echo '{"value":'$(pamixer --get-volume)',"muted":"'$(pamixer --get-mute)'"}'
}
volume
pw-mon -oa | stdbuf -o0 grep -os "changed:" | while read -r line; do
volume
done

View file

@ -1,8 +1,9 @@
{ config, pkgs, lib, ... }:
let
scripts = ../../scripts;
modifier = "SUPER";
terminal = "alacritty";
inherit (config) platform;
scripts = ../../scripts;
modifier = "SUPER";
terminal = "alacritty";
in {
home.packages = with pkgs; [
swaybg
@ -11,7 +12,7 @@ in {
wayland.windowManager.hyprland = {
enable = true;
enableNvidiaPatches = config.platform == "desktop";
enableNvidiaPatches = platform == "desktop";
systemd.enable = true;
xwayland.enable = true;
@ -21,7 +22,7 @@ in {
"$menu" = "rofi -show drun";
exec-once = [
"background=${../../assets/background.png} ${scripts}/autostart"
"background=${../../assets/background.png} platform=${platform} ${scripts}/autostart"
];
general = {
@ -149,7 +150,7 @@ in {
audio-disp = "${scripts}/multimedia Volume pamixer $(pamixer --get-volume)";
audio = cmd: "pamixer ${cmd} && ${audio-disp}";
# Brightness using brightnessctl
brightness-disp = ''${scripts}/multimedia Brightness brightnessctl $(brightnessctl -e -m | cut -d "," -f4 | tr -d "%")'';
brightness-disp = ''${scripts}/multimedia Brightness brightnessctl $(brightnessctl -e -m | cut -d, -f4 | tr -d "%")'';
brightness = x: "brightnessctl -e set ${x} && ${brightness-disp}";
in [
# XF86 key bindings

View file

@ -57,6 +57,12 @@
xdg.configFile.rofi.source = ./rofi;
# EWW
programs.eww.enable = true;
programs.eww.package = pkgs.eww-wayland;
programs.eww.configDir = ./eww;
# Mako
services.mako = {

View file

@ -1,9 +1,12 @@
#!/usr/bin/env bash
# Background
swaybg -o '*' -i "$background" -m fill &
waybar &
# Status Bar
eww open "$platform"_bar --screen 0
# Idle Handler
swayidle timeout 120 'swaylock -f --grace=180' \
timeout 600 'systemctl suspend' \
before-sleep 'swaylock -f' &