initial commit
This commit is contained in:
commit
1eca57b40e
9 files changed
+441
No files matched your search
@@ -0,0 +1,24 @@
|
|||||||
|
(include "bar/widget.yuck")
|
||||||
|
|
||||||
|
(include "bar/widgets/sys.yuck")
|
||||||
|
(include "bar/widgets/wss.yuck")
|
||||||
|
(include "bar/widgets/info.yuck")
|
||||||
|
|
||||||
|
(defwidget bar [monitor]
|
||||||
|
(centerbox :class "bar" :orientation "h"
|
||||||
|
(bar-left)
|
||||||
|
(bar-center :monitor monitor)
|
||||||
|
(bar-right)))
|
||||||
|
|
||||||
|
(defwidget bar-left []
|
||||||
|
(box :class "bar-left" :space-evenly false :halign "start"
|
||||||
|
(bat) (cpu) (temp) (mem) (disk)))
|
||||||
|
|
||||||
|
(defwidget bar-center [monitor]
|
||||||
|
(box :class "bar-center" :space-evenly false
|
||||||
|
(workspaces :monitor monitor)))
|
||||||
|
|
||||||
|
(defwidget bar-right []
|
||||||
|
(box :class "bar-right" :space-evenly false :halign "end"
|
||||||
|
(brightness) (vol) (net) (date) (time)))
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
(defvar eww "eww")
|
||||||
|
|
||||||
|
(defwidget metric [label value min max onchange]
|
||||||
|
(box :orientation "h"
|
||||||
|
:class "metric mod"
|
||||||
|
:space-evenly false
|
||||||
|
(box :class "label" label)
|
||||||
|
(scale :min min
|
||||||
|
:max max
|
||||||
|
:active {onchange != ""}
|
||||||
|
:value value
|
||||||
|
:onchange onchange)))
|
||||||
|
|
||||||
|
(defwidget hover-metric [icon value ?class revealname reveal onchange]
|
||||||
|
(eventbox :onhover "${eww} update ${revealname}=true"
|
||||||
|
:onhoverlost "${eww} update ${revealname}=false"
|
||||||
|
(box :orientation "h"
|
||||||
|
:class "metric mod"
|
||||||
|
:space-evenly false
|
||||||
|
(box :class {class ?: ""} {icon})
|
||||||
|
(revealer :transition "slideleft"
|
||||||
|
:reveal reveal
|
||||||
|
:duration "300ms"
|
||||||
|
(scale :min 0
|
||||||
|
:max 100
|
||||||
|
:value value
|
||||||
|
:onchange onchange)))))
|
||||||
|
|
||||||
|
(defwidget hover-text [icon value ?class revealname reveal]
|
||||||
|
(eventbox :onhover "${eww} update ${revealname}=true"
|
||||||
|
:onhoverlost "${eww} update ${revealname}=false"
|
||||||
|
(box :orientation "h"
|
||||||
|
:class "metric mod"
|
||||||
|
:space-evenly false
|
||||||
|
(box :class {class ?: ""} {icon})
|
||||||
|
(revealer :transition "slideleft"
|
||||||
|
:reveal net_reveal
|
||||||
|
:duration "300ms"
|
||||||
|
(label :text {value}
|
||||||
|
:class "purple")))))
|
||||||
|
|
||||||
|
(defwidget status [label poll]
|
||||||
|
(box :orientation "h"
|
||||||
|
:class "metric mod"
|
||||||
|
:space-evenly false
|
||||||
|
(box :class "label" label)
|
||||||
|
(text :poll poll)))
|
||||||
|
|
||||||
|
(defwidget text [poll]
|
||||||
|
(box :class "text mod"
|
||||||
|
poll))
|
||||||
|
|
||||||
|
(defwidget circle [value ?icon class]
|
||||||
|
(box :class "mod"
|
||||||
|
(circular-progress :value value
|
||||||
|
:width 30
|
||||||
|
:class "circle-bar ${class}"
|
||||||
|
:thickness 4
|
||||||
|
:start-at 75
|
||||||
|
(label :text {icon ?: ""}
|
||||||
|
:class "circle ${class}"))))
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
(defvar vol_reveal false)
|
||||||
|
(defvar bright_reveal false)
|
||||||
|
(defvar net_reveal false)
|
||||||
|
|
||||||
|
(defpoll vol :interval "2s" "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{print $2 * 100}'")
|
||||||
|
(defwidget vol []
|
||||||
|
(hover-metric :icon {vol < 33 ? "" : vol < 66 ? "" : ""}
|
||||||
|
:value vol
|
||||||
|
:class "green"
|
||||||
|
:revealname "vol_reveal"
|
||||||
|
:reveal vol_reveal
|
||||||
|
:onchange "wpctl set-volume @DEFAULT_SINK@ {}% && eww update vol={}"))
|
||||||
|
|
||||||
|
(defpoll bright :interval "10s" "light")
|
||||||
|
(defwidget brightness []
|
||||||
|
(hover-metric :icon ""
|
||||||
|
:value bright
|
||||||
|
:class "yellow"
|
||||||
|
:revealname "bright_reveal"
|
||||||
|
:reveal bright_reveal
|
||||||
|
:onchange "light -S {}%"))
|
||||||
|
|
||||||
|
(defpoll net :interval "2s" "iw dev wlan0 link | awk 'NR==2 {print $2}'")
|
||||||
|
(defwidget net []
|
||||||
|
(hover-text :icon " "
|
||||||
|
:value net
|
||||||
|
:class "cyan"
|
||||||
|
:revealname "net_reveal"
|
||||||
|
:reveal net_reveal))
|
||||||
|
|
||||||
|
(defpoll time :interval "1s" "date '+%H:%M:%S'")
|
||||||
|
(defwidget time []
|
||||||
|
(text :poll time))
|
||||||
|
|
||||||
|
(defpoll date :interval "10s" "date '+%y-%m-%d'")
|
||||||
|
(defwidget date []
|
||||||
|
(text :poll date))
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
(defwidget cpu []
|
||||||
|
(circle :value {EWW_CPU.avg}
|
||||||
|
:icon ""
|
||||||
|
:class "cyan"))
|
||||||
|
|
||||||
|
(defwidget temp []
|
||||||
|
(circle :value {EWW_TEMPS.CORETEMP_PACKAGE_ID_0}
|
||||||
|
:icon ""
|
||||||
|
:class "magenta"))
|
||||||
|
|
||||||
|
(defwidget mem []
|
||||||
|
(circle :value {EWW_RAM.used_mem_perc}
|
||||||
|
:icon ""
|
||||||
|
:class "yellow"))
|
||||||
|
|
||||||
|
(defwidget disk []
|
||||||
|
(circle :value {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)}
|
||||||
|
:icon ""
|
||||||
|
:class "red"))
|
||||||
|
|
||||||
|
(defwidget bat []
|
||||||
|
(circle :value {EWW_BATTERY.BAT0.capacity}
|
||||||
|
:icon "⏻"
|
||||||
|
:class "green"))
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
;; (deflisten wslist0
|
||||||
|
;; "scripts/getwss eDP-1")
|
||||||
|
;; (deflisten wslist1
|
||||||
|
;; "scripts/getwss DP-")
|
||||||
|
(deflisten wslist0
|
||||||
|
"scripts/getwss 0")
|
||||||
|
(deflisten wslist1
|
||||||
|
"scripts/getwss 1")
|
||||||
|
(defwidget workspaces [monitor]
|
||||||
|
(box :class "workspaces"
|
||||||
|
(for entry in {monitor == 0 ? wslist0 : wslist1}
|
||||||
|
(button :class "${
|
||||||
|
entry.urgent ? "urgent"
|
||||||
|
: entry.focused ? "focused"
|
||||||
|
: "unfocused"
|
||||||
|
} id${entry.id}"
|
||||||
|
:onclick "hyprctl dispatch workspace ${entry.id}"
|
||||||
|
{entry.name}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
$white: #BAC2DE;
|
||||||
|
$black: #45475A;
|
||||||
|
$black2: #585B70;
|
||||||
|
$red: #F38BA8;
|
||||||
|
$green: #A6E3A1;
|
||||||
|
$yellow: #F9E2AF;
|
||||||
|
$blue: #89B4FA;
|
||||||
|
$magenta: #F5C2E7;
|
||||||
|
$cyan: #94E2D5;
|
||||||
|
|
||||||
|
$magenta3: #e6aaee;
|
||||||
|
$purple: #b0b0e8;
|
||||||
|
|
||||||
|
$text: $white;
|
||||||
|
$mod-bg: #505060;
|
||||||
|
$trough: #464666;
|
||||||
|
$bg: rgba(#1e1e2e, .7);
|
||||||
|
$hover-bg: $black;
|
||||||
|
|
||||||
|
* {
|
||||||
|
all: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
margin-top: 10px;
|
||||||
|
color: $text;
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: "Symbols Nerd Font", "Comic Code Ligatures";
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mod {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric scale trough highlight {
|
||||||
|
background-color: $magenta;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric scale trough {
|
||||||
|
background-color: $trough;
|
||||||
|
border-radius: 50px;
|
||||||
|
min-height: 6px;
|
||||||
|
min-width: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces button:hover {
|
||||||
|
background-color: $hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces {
|
||||||
|
// un... un bro momento
|
||||||
|
.id1 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.id2 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.id3 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.id6 {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.id7 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.id8 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0 7px;
|
||||||
|
margin: 0 3px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: $text;
|
||||||
|
border: 2px solid;
|
||||||
|
border-color: $black2;
|
||||||
|
}
|
||||||
|
button.focused {
|
||||||
|
border-color: $magenta3;
|
||||||
|
color: $purple;
|
||||||
|
}
|
||||||
|
button.urgent {
|
||||||
|
background-color: $magenta;
|
||||||
|
color: $black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green {
|
||||||
|
color: $green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellow {
|
||||||
|
color: $yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
color: $blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.magenta {
|
||||||
|
color: $magenta;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cyan {
|
||||||
|
color: $cyan;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purple {
|
||||||
|
color: $purple;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-bar {
|
||||||
|
background-color: $bg;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
(include "bar/bar.yuck")
|
||||||
|
|
||||||
|
(defwindow bar-eDP
|
||||||
|
:monitor 0
|
||||||
|
:exclusive true
|
||||||
|
:geometry (geometry :x "0%"
|
||||||
|
:y "0%"
|
||||||
|
:width "100%"
|
||||||
|
:height "30px"
|
||||||
|
:anchor "top center")
|
||||||
|
(bar :monitor 0))
|
||||||
|
|
||||||
|
(defwindow bar-HDMI
|
||||||
|
:monitor 1
|
||||||
|
:exclusive true
|
||||||
|
:geometry (geometry :x "0%"
|
||||||
|
:y "0%"
|
||||||
|
:width "100%"
|
||||||
|
:height "30px"
|
||||||
|
:anchor "top center")
|
||||||
|
(bar :monitor 1))
|
||||||
Executable
+118
@@ -0,0 +1,118 @@
|
|||||||
|
#!/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
NAME = [
|
||||||
|
"?",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"♪",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class State:
|
||||||
|
wss: dict
|
||||||
|
mname: str
|
||||||
|
focused: bool
|
||||||
|
prev_active: int
|
||||||
|
|
||||||
|
def handle(state: State, event: str, data: str = None):
|
||||||
|
wss = state.wss
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if event == "focusedmon":
|
||||||
|
state.focused = data[:-2] == state.mname
|
||||||
|
if not state.focused:
|
||||||
|
return
|
||||||
|
|
||||||
|
if event == "workspace":
|
||||||
|
wid = int(data)
|
||||||
|
if state.prev_active in wss.keys():
|
||||||
|
wss[state.prev_active]['focused'] = False
|
||||||
|
wss[wid]['focused'] = True
|
||||||
|
state.prev_active = wid
|
||||||
|
return output(state)
|
||||||
|
if event == "createworkspace":
|
||||||
|
wss[int(data)] = new_ws(int(data), True, False)
|
||||||
|
state.wss = dict(sorted(wss.items()))
|
||||||
|
return output(state)
|
||||||
|
if event == "destroyworkspace":
|
||||||
|
del wss[int(data)]
|
||||||
|
return output(state)
|
||||||
|
|
||||||
|
def output(state: State):
|
||||||
|
print(json.dumps(list(state.wss.values())), flush=True)
|
||||||
|
|
||||||
|
def main(mid: str):
|
||||||
|
state = get_state(mid)
|
||||||
|
output(state)
|
||||||
|
|
||||||
|
isig = os.getenv("HYPRLAND_INSTANCE_SIGNATURE")
|
||||||
|
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
client.connect(f"/tmp/hypr/{isig}/.socket2.sock")
|
||||||
|
while True:
|
||||||
|
r = client.recv(1024)
|
||||||
|
if not r:
|
||||||
|
break
|
||||||
|
msgs = r.decode().strip().split("\n")
|
||||||
|
for msg in msgs:
|
||||||
|
parts = msg.split(">>")
|
||||||
|
handle(state, *parts)
|
||||||
|
|
||||||
|
def get_state(mid: str):
|
||||||
|
mid = int(mid)
|
||||||
|
res = subprocess.run(
|
||||||
|
["hyprctl", "monitors", "-j"],
|
||||||
|
capture_output=True
|
||||||
|
)
|
||||||
|
raw_mons = json.loads(res.stdout)
|
||||||
|
res = subprocess.run(
|
||||||
|
["hyprctl", "workspaces", "-j"],
|
||||||
|
capture_output=True
|
||||||
|
)
|
||||||
|
raw_wss = json.loads(res.stdout)
|
||||||
|
|
||||||
|
mname: str = None
|
||||||
|
activews: int = None
|
||||||
|
focused: bool = None
|
||||||
|
for m in raw_mons:
|
||||||
|
if m['id'] == mid:
|
||||||
|
activews = int(m['activeWorkspace']['id'])
|
||||||
|
mname = m['name']
|
||||||
|
focused = m['focused']
|
||||||
|
break
|
||||||
|
if mname is None:
|
||||||
|
print("Error: monitor not found")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
wss = dict()
|
||||||
|
for ws in raw_wss:
|
||||||
|
if ws['monitor'] == mname:
|
||||||
|
wid = int(ws['id'])
|
||||||
|
wss[wid] = new_ws(wid, wid == activews, False)
|
||||||
|
wss = dict(sorted(wss.items()))
|
||||||
|
return State(wss, mname, focused, activews)
|
||||||
|
|
||||||
|
def new_ws(wid, focused, urgent):
|
||||||
|
return {
|
||||||
|
'id': wid,
|
||||||
|
'name': NAME[wid],
|
||||||
|
'focused': focused,
|
||||||
|
'urgent': urgent
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main(*sys.argv[1:])
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
Reference in new issue
Block a user