Update eww and hyprland

This commit is contained in:
2024-07-07 13:41:37 +03:00
parent c775fb987e
commit 77077b0192
29 changed files with 450 additions and 298 deletions
+1 -1
View File
@@ -3,6 +3,6 @@
(defwidget active-window []
(box
:halign "center"
(label :class "box" :text "${window?: 'none'}")
(label :class "bar-group" :text "${window?: 'none'}")
)
)
-24
View File
@@ -1,24 +0,0 @@
(defpoll volume-level :interval "1s" "./lib/get-volume-level.sh")
(defwidget icon []
(label :text {volume-level > 66 ? "" : volume-level > 0 ? "" : ""})
)
; TODO figure out the sink IDs dynamically?
(defwidget audio []
(box
:orientation "h"
:space-evenly false
:halign "end"
(eventbox :cursor "pointer" (button :class "audio-source interactive" :onclick "pactl set-default-sink 57" "󰍹"))
(eventbox :cursor "pointer" (button :class "audio-source-2 interactive" :onclick "pactl set-default-sink 64" "󰋋"))
(eventbox :cursor "pointer" :class "interactive" :onscroll "./lib/change-volume.sh {}"
(box :class "volume"
(icon)
(button :onclick "pavucontrol &"
(label :text "${volume-level}%")
)
))
)
)
+11 -14
View File
@@ -1,27 +1,24 @@
(include "./bar/active-window.yuck")
(include "./bar/audio.yuck")
; (include "./bar/brightness.yuck")
(include "./bar/active-window.yuck")
(include "./bar/clock.yuck")
(include "./bar/kbd-layout.yuck")
(include "./bar/media.yuck")
(include "./bar/power.yuck")
(include "./bar/weather.yuck")
(include "./bar/workspaces.yuck")
(defwidget right []
(box :class "box right"
(defwidget bar-tray []
(box :class "bar-group"
:orientation "h"
:halign "end"
:space-evenly false
(systray :hexpand true :class "systray" :icon-size 18 :spacing 4)
(kbd-layout)
(audio)
(media)
(kbd-layout-tray-item)
(media-tray-item)
; (brightness)
(clock)
(eventbox :cursor "pointer"
(button :class "power-button interactive" :onclick "eww open --toggle power-menu" "󰐥")
)
(weather-tray-item)
(clock-tray-item)
(power-tray-item)
)
)
@@ -29,7 +26,7 @@
(box :class "bar" :orientation "h"
(workspaces :monitor-workspaces monitor-workspaces)
(active-window)
(right)
(bar-tray)
)
)
+2 -2
View File
@@ -18,8 +18,8 @@
)
)
(defwidget clock []
(box :class "clock"
(defwidget clock-tray-item []
(box :class "clock-tray-item"
:orientation "h"
:space-evenly false
:valign "center"
+10 -6
View File
@@ -1,13 +1,17 @@
(defwidget kbd-layout []
(deflisten keyboard-layout :initial "en" "./lib/get-kb-layout.sh")
(defwidget kbd-layout-tray-item []
(box
:orientation "h"
:space-evenly false
:halign "center"
:class "interactive"
(eventbox :cursor "pointer" :class "interactive" :onclick "hyprctl switchxkblayout usb-hid-keyboard next"
(label :text {keyboard-layout} :class "kbd-layout")
:class "interactive kbd-layout-tray-item"
(eventbox :cursor "pointer" :class "interactive"
(button
:class "kbd-layout"
:onclick "hyprctl switchxkblayout usb-hid-keyboard next"
keyboard-layout
)
)
)
)
(deflisten keyboard-layout :initial "en" "python ./lib/get-kb-layout.py")
+50 -16
View File
@@ -1,15 +1,45 @@
(defpoll mediastatus :interval "1s" "./lib/media-status.sh")
(defpoll audio-sinks :interval "1s" "pactl -f json list sinks")
(defpoll audio-info :initial "{}" :interval "1s" "pactl -f json info")
(defpoll volume-level :interval "1s" "./lib/get-volume-level.sh")
(defwidget media []
(eventbox :cursor "pointer" :onmiddleclick "playerctl play-pause"
(button :class "media-status interactive" :onclick "eww open --toggle media-menu"
(label :text "${mediastatus.status == "Playing" ? "" : mediastatus.status == "Paused" ? "" : ""}")
)
)
(defwidget media-tray-item []
(box :orientation "h" :space-evenly false :halign "end" :class "media-tray-item"
(eventbox
:cursor "pointer"
:class "interactive"
:onscroll "./lib/change-volume.sh {}"
:onclick "eww open --toggle media-menu"
:onmiddleclick "playerctl play-pause"
(box :class "volume-tray-icon"
(label :class "volume-icon" :text {volume-level > 66 ? "" : volume-level > 0 ? "" : ""})
(label :text "${volume-level}%")
))
)
)
(defwidget media_full []
(box :orientation "v" :space-evenly false :class "media-window"
(defwidget audio-source-selector []
(box :orientation "v" :valign "start" :class "audio-source-selector"
(box :class "title"
(label :halign "start" :text "output source")
)
(for sink in audio-sinks
(eventbox :cursor "pointer"
(button
:halign "start"
:class "audio-source interactive ${sink.name == audio-info.default_sink_name ? "active" : ""}"
:onclick "pactl set-default-sink ${sink.index}"
"󰓃 ${sink.description}"
)
)
)
)
)
(defwidget media-player []
(box :orientation "v" :space-evenly false :class "media-player" :valign "top"
(label :class "title" :text "${mediastatus.artist} - ${mediastatus.title}" :show-truncated false)
(label :class "album" :text "${mediastatus.album}" :show-truncated false)
(box :class "media-cover" :style "background: url('${mediastatus.artUrl}'); background-size: cover;" :height 300)
@@ -35,7 +65,7 @@
(button :class "media-button" :onclick "playerctl next" "")
)
(eventbox :cursor "pointer"
(eventbox :cursor "pointer"
(button
:class "media-button loop ${mediastatus.loop != "None" ? "active" : ""}"
:onclick "playerctl loop ${mediastatus.loop == "Playlist" ? "track" : mediastatus.loop == "Track" ? "none" : "playlist"}"
@@ -52,14 +82,18 @@
:monitor 0
:namespace "media-menu"
:stacking "overlay"
:geometry (geometry :x "8px"
:y "8px"
:width "400px"
:anchor "top right"
)
:geometry (geometry :x "8px" :y "8px" :width "400px" :anchor "top right")
:wm-ignore false
:focusable false
(box :class "control-centre"
(media_full)
(box :class "eww-overlay media-menu" :orientation "v" :space-evenly false
(media-player)
(audio-source-selector)
(eventbox :cursor "pointer"
(button :class "interactive btn" :halign "start" :onclick "pavucontrol &" "󰴸 Open PulseAudio control")
)
; TODO: For some reason audio-info is null if I don't invoke it outside the for. Investigate.x
(label :class "hidden" :text "Default: ${audio-info.default_sink_name}")
)
)
+31
View File
@@ -0,0 +1,31 @@
(defwidget power-tray-item []
(eventbox :cursor "pointer"
(button :class "power-button-tray-item interactive" :onclick "eww open --toggle power-menu" "󰐥")
)
)
(defwindow power-menu
:namespace "power-menu"
:monitor 0
:stacking "overlay"
:geometry (geometry :x "50%"
:y "50%"
:width "30%"
:height "200px"
:anchor "center"
)
(box :class "power-menu" :orientation "h"
(eventbox :cursor "pointer"
(button :class "power-menu-item first" :onclick "eww open --toggle power-menu & ./lib/lock.sh" "")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "eww open --toggle power-menu & ./lib/logout.sh" "󰈆")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "eww open --toggle power-menu & ./lib/reboot.sh" "")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "eww open --toggle power-menu & ./lib/shutdown.sh" "")
)
)
)
+14
View File
@@ -0,0 +1,14 @@
(deflisten weather :initial "{'temp': 'n/a', 'desc': 'n/a'}" "./lib/weather.py")
(defwidget weather-tray-item []
(box :class "weather-tray-item"
:orientation "h"
:space-evenly false
(eventbox :cursor "pointer" :class "interactive weather" :onclick "xdg-open https://sinoptik.bg"
(box :space-evenly false
(label :class "weather-temp" :text "${weather.icon} ${weather.temp}")
(label :class "weather-desc" :text "${weather.desc}")
)
)
)
)
+45 -167
View File
@@ -1,23 +1,62 @@
* {
all: unset;
font-family: "SF Pro Light";
}
$font: "SF Pro Light";
$bg: rgba(0, 0, 0, 0.5);
$fg: #dedede;
$menu-border: rgba(255, 255, 255, 0.1);
$bar-gap: 8px;
* {
all: unset;
font-family: $font;
}
@import "./styles/media-menu.scss";
@import "./styles/power-menu.scss";
@import "./styles/tray.scss";
.eww-overlay {
background-color: $bg;
border: 3px solid $menu-border;
border-radius: 8px;
padding: 16px 48px;
}
.bar-group {
background-color: $bg;
border-radius: 8px;
padding: 0 calc($bar-gap * 1.5);
color: $fg;
> :not(:first-child) {
margin-left: $bar-gap;
}
}
.interactive {
border-radius: 4px;
margin: 4px 0;
transition: background-color 0.4s ease;
&.active {
background-color: $fg;
color: $bg;
font-weight: bold;
}
&:not(.active):hover {
background-color: rgba(255, 255, 255, 0.2);
}
}
.btn {
border-radius: 4px;
padding: 10px 15px 10px 10px;
}
.hidden {
opacity: 0;
}
.workspace {
padding: 0 8px;
@@ -27,164 +66,3 @@ $bar-gap: 8px;
font-weight: bold;
}
}
.box {
background-color: $bg;
border-radius: 8px;
padding: 0 calc($bar-gap * 1.5);
color: $fg;
}
.right > :not(:first-child) {
margin-left: $bar-gap;
}
.audio-source {
padding-top: 2px;
padding-left: 8px;
padding-right: 12px;
}
.audio-source-2 {
padding-left: 8px;
padding-right: 10px;
}
.volume {
padding-right: 6px;
}
.kbd-layout {
padding: 0 8px;
border-radius: 4px;
}
.media-status {
padding-right: 10px;
padding-left: 8px;
}
.control-centre {
background-color: $bg;
border: 3px solid $menu-border;
border-radius: 8px;
padding: 16px 48px;
.media-window {
.title {
font-weight: bold;
font-size: 15px;
};
.album {
font-size: 13px;
color: #aaa
}
.media-cover {
margin-top: 12px;
border-radius: 16px;
border: 2px solid $menu-border;
}
.media-controls {
margin-top: 16px;
}
.media-button {
padding: 8px 13px;
border-radius: 100%;
border: 2px solid $menu-border;
transition: all 0.4s ease;
&.shuffle {
padding-left: 10px;
padding-right: 16px;
&.active {
background-color: $fg;
color: $bg;
}
}
&.loop {
padding-left: 12px;
padding-right: 14px;
&.active {
background-color: $fg;
color: $bg;
}
}
&.pause {
background-color: $fg;
color: $bg;
}
&:hover {
background-color: $fg;
border-color: $fg;
color: $bg;
}
}
}
}
.power-menu {
background-color: $bg;
border: 3px solid $menu-border;
border-radius: 32px;
.power-menu-item {
font-size: 44px;
background-color: $bg;
border-radius: 20px;
border: 1px solid $menu-border;
margin: 16px 0;
margin-right: 16px;
padding-right: 4px; /* this makes sure icons from nerd font are centered */
transition: background-color 0.4s ease, color 0.4s ease;
color: $fg;
&:hover {
background-color: $fg;
color: $bg;
}
&.first {
margin-left: 16px;
}
}
}
.power-button {
padding-right: 8px;
padding-left: 8px;
margin-left: 4px;
font-size: 18px;
}
.clock {
margin-right: 8px;
.date {
border: 1px solid rgba(255, 255, 255, 0.3);
border-top: 4px solid rgba(255, 255, 255, 0.6);
padding: 0 8px;
border-radius: 4px;
margin: 6px 0;
font-size: 12px;
}
.day {
margin-left: 6px;
}
.time {
margin-left: 8px;
}
}
-2
View File
@@ -1,5 +1,3 @@
(include "./power-menu/power-menu.yuck")
(include "./bar/bar.yuck")
; a hacky solution for moving the windows on my second monitor a bit up so I can see them :D
+1
View File
@@ -0,0 +1 @@
secrets.py
+8 -10
View File
@@ -1,16 +1,14 @@
#!/usr/bin/env sh
DaySuffix() {
case `date +%-d` in
1|21|31) echo "st";;
2|22) echo "nd";;
3|23) echo "rd";;
*) echo "th";;
esac
}
day=$(date "+%a")
date=$(date "+%-d")
time=$(date "+%H:%M")
echo "{\"date\": \"$date\", \"day\": \"$day\", \"time\": \"$time\"}"
JSON_STRING=$(jq -n \
--arg day "$day" \
--arg date "$date" \
--arg time "$time" \
'{day: $day, date: $date, time: $time}')
echo $JSON_STRING
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env python
from hyprsocket import run_on_line
def get_kb_layout(line):
if "activelayout" in line:
res = line.split(">>")[1]
language = res.split(",")[1]
lang_short = language[0:2]
print("bg" if lang_short == "Bu" else "en", flush=True)
run_on_line(get_kb_layout)
+17
View File
@@ -0,0 +1,17 @@
##!/usr/bin/env sh
socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do
if [[ $line == "activelayout>>"* ]]; then
split=(${line//>>/ })
lang=(${split[1]//,/ })
language=${lang[1]}
lang_code=${language:0:2}
lang_code_lower=$(echo $lang_code | tr '[:upper:]' '[:lower:]')
if [[ $lang_code_lower == "bu" ]]; then
lang_code_lower="bg"
fi
echo $lang_code_lower
fi
done
+4 -1
View File
@@ -12,7 +12,10 @@ fi
if [[ $volume_value =~ ^" 1" ]]; then
echo "${volume_value//.}"
# starts with a space - trim
trimmed=$( echo $volume_value | cut -c1- )
echo "${trimmed//.}"
exit 0
fi
+17 -15
View File
@@ -1,21 +1,23 @@
#!/usr/bin/env sh
status=$(playerctl status 2>/dev/null)
artist=$(playerctl metadata --format "{{artist}}" 2>/dev/null)
title=$(playerctl metadata --format "{{title}}" 2>/dev/null)
album=$(playerctl metadata --format "{{album}}" 2>/dev/null)
artUrl=$(playerctl metadata --format "{{mpris:artUrl}}" 2>/dev/null)
length=$(playerctl metadata --format "{{duration(mpris:length)}}" 2>/dev/null)
artist=$(playerctl metadata -f "{{artist}}" 2>/dev/null)
title=$(playerctl metadata -f "{{title}}" 2>/dev/null)
album=$(playerctl metadata -f "{{album}}" 2>/dev/null)
artUrl=$(playerctl metadata -f "{{mpris:artUrl}}" 2>/dev/null)
length=$(playerctl metadata -f "{{duration(mpris:length)}}" 2>/dev/null)
shuffle=$(playerctl shuffle 2>/dev/null)
loop=$(playerctl loop 2>/dev/null)
echo "{
\"status\": \"$status\",
\"artist\": \"$artist\",
\"title\": \"$title\",
\"album\": \"$album\",
\"artUrl\": \"$artUrl\",
\"length\": \"$length\",
\"shuffle\": \"$shuffle\",
\"loop\": \"$loop\"
}"
JSON_STRING=$(jq -n \
--arg status "$status" \
--arg artist "$artist" \
--arg title "$title" \
--arg album "$album" \
--arg artUrl "$artUrl" \
--arg length "$length" \
--arg shuffle "$shuffle" \
--arg loop "$loop" \
'{status: $status, artist: $artist, title: $title, album: $album, artUrl: $artUrl, length: $length, shuffle: $shuffle, loop: $loop}')
echo $JSON_STRING
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env python
import requests, json, sys, time
from secrets import WEATHER_API_TOKEN, WEATHER_CITY
UNITS = "metric"
LANG = "en"
def get_icon(code):
icons = {
"01d": "",
"01n": "",
"02d": "",
"02n": "",
"03d": "󰖐",
"03n": "󰖐",
"04d": "",
"04n": "",
"09d": "",
"09n": "",
"10d": "",
"10n": "",
"11d": "",
"11n": "",
"13d": "󰖘",
"13n": "󰖘",
"50d": "",
"50n": "",
}
try:
return icons[code]
except KeyError:
return None
def main():
response = requests.get(
f"https://api.openweathermap.org/data/2.5/weather?q={WEATHER_CITY}&appid={WEATHER_API_TOKEN}&lang={LANG}&units={UNITS}"
).json()
data = {
"icon": get_icon(response["weather"][0]["icon"]),
"temp": str(round(response["main"]["temp"])) + "°",
"desc": response["weather"][0]["description"].capitalize(),
}
return data
if __name__ == "__main__":
try:
while True:
try:
sys.stdout.write(json.dumps(main()) + "\n")
sys.stdout.flush()
time.sleep(1800)
except requests.exceptions.ConnectionError:
print("Connection error! Retrying...")
time.sleep(2)
except KeyboardInterrupt:
exit(0)
@@ -1,26 +0,0 @@
(defwindow power-menu
:namespace "power-menu"
:monitor 0
:stacking "overlay"
:geometry (geometry :x "50%"
:y "50%"
:width "30%"
:height "200px"
:anchor "center"
)
(box :class "power-menu" :orientation "h"
(eventbox :cursor "pointer"
(button :class "power-menu-item first" :onclick "./power-menu/lock.sh" "")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "./power-menu/logout.sh" "󰈆")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "./power-menu/reboot.sh" "")
)
(eventbox :cursor "pointer"
(button :class "power-menu-item" :onclick "./power-menu/shutdown.sh" "")
)
)
)
+78
View File
@@ -0,0 +1,78 @@
.media-menu {
.audio-source-selector {
margin-top: 16px;
margin-bottom: 8px;
.title {
border-bottom: 1px solid $fg;
padding: 10px;
margin-bottom: 8px;
}
.audio-source {
padding-left: 10px;
padding-right: 15px;
}
}
.media-player {
.title {
font-weight: bold;
font-size: 15px;
}
.album {
font-size: 13px;
color: #aaa;
}
.media-cover {
margin-top: 12px;
border-radius: 16px;
border: 2px solid $menu-border;
}
.media-controls {
margin-top: 16px;
}
.media-button {
padding: 8px 13px;
border-radius: 100%;
border: 2px solid $menu-border;
transition: all 0.4s ease;
&.shuffle {
padding-left: 10px;
padding-right: 16px;
&.active {
background-color: $fg;
color: $bg;
}
}
&.loop {
padding-left: 12px;
padding-right: 14px;
&.active {
background-color: $fg;
color: $bg;
}
}
&.pause {
background-color: $fg;
color: $bg;
}
&:hover {
background-color: $fg;
border-color: $fg;
color: $bg;
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
.power-menu {
background-color: $bg;
border: 3px solid $menu-border;
border-radius: 32px;
.power-menu-item {
font-size: 44px;
background-color: $bg;
border-radius: 20px;
border: 1px solid $menu-border;
margin: 16px 0;
margin-right: 16px;
padding-right: 4px; /* this makes sure icons from nerd font are centered */
transition:
background-color 0.4s ease,
color 0.4s ease;
color: $fg;
&:hover {
background-color: $fg;
color: $bg;
}
&.first {
margin-left: 16px;
}
}
}
+65
View File
@@ -0,0 +1,65 @@
$tray-item-interactive-margin: 6px 0;
.kbd-layout-tray-item {
margin: $tray-item-interactive-margin;
.kbd-layout {
padding: 0 8px;
border-radius: 4px;
}
}
.media-tray-item {
margin: $tray-item-interactive-margin;
.volume-tray-icon {
padding-right: 6px;
.volume-icon {
padding-right: 6px;
}
}
}
.clock-tray-item {
margin-right: 8px;
.date {
border: 1px solid rgba(255, 255, 255, 0.3);
border-top: 4px solid rgba(255, 255, 255, 0.6);
padding: 0 8px;
border-radius: 4px;
margin: 8px 0;
font-size: 12px;
}
.day {
margin-left: 6px;
}
.time {
margin-left: 4px;
}
}
.weather-tray-item {
margin: $tray-item-interactive-margin;
.weather-temp {
padding-left: 8px;
}
.weather-desc {
padding-left: 4px;
padding-right: 8px;
}
}
.power-button-tray-item {
margin: $tray-item-interactive-margin;
padding-right: 8px;
padding-left: 8px;
margin-left: 4px;
font-size: 18px;
}
+4
View File
@@ -5,5 +5,9 @@
exec-once = eww open bar --id bar1 --arg monitor=0 --arg monitor-workspaces="[1,2]"
exec-once = eww open bar --id bar2 --arg monitor=1 --arg monitor-workspaces="[3,4]"
exec-once = eww open --toggle monitor-bump
exec-once = swww-daemon --format xrgb &
exec-once = swaync &
exec-once = blueman-applet &
+2
View File
@@ -11,6 +11,8 @@ windowrulev2 = float, class:(steam), title:(Friends List)
windowrulev2 = float, class:(steam), title:(Steam Settings)
# blur eww windows
layerrule = blur, eww-overlay
layerrule = ignorezero, eww-overlay
layerrule = blur, power-menu
layerrule = ignorezero, power-menu
layerrule = blur, media-menu