Closed 01micko closed 2 years ago
Can you try the current git version please? Hopefully, these should be fixed.
Can you try the current git version please? Hopefully, these should be fixed.
Perfect. Thank you :smile:
Hmm, reopening,
Getting a segfault - seems random, not sure how to trigger, but the segfault did happen when the flowgrid error was apparent, so could be related. Might be tricky to get a backtrace because it ran all night fine but seems random while working.
[ 2108.288418] sfwbar[9466]: segfault at 31 ip 0000000000419a1f sp 00007fff70e9ddf0 error 4 in sfwbar[409000+1a000]
[ 2108.288435] Code: c8 48 89 d6 48 89 c7 e8 ef fa fe ff 48 89 c7 e8 8d f1 ff ff 48 89 45 d8 48 8b 45 d8 48 8b 40 18 48 89 45 f8 eb 3e 48 8b 45 f8 <48> 8b 00 48 89 c7 e8 1b 34 ff ff 48 39 45 c0 75 0f 48 8b 45 f8 48
BTW - only my bar is crashing.
launcher seems rock solid though it is a very simple config and is started 2 seconds after the main bar.
Aha.. pcmanfm
is crashing the bar and I got a backtrace.
Found ninja-1.10.2 at /usr/bin/ninja
/mnt/home/micko/sfwbar-10$ ninja -C build/
ninja: Entering directory `build/'
[37/37] Linking target sfwbar
/mnt/home/micko/sfwbar-10$ build/sfwbar
=================================================================
==4008==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000748788 at pc 0x000000437dac bp 0x7ffe547dff50 sp 0x7ffe547dff48
READ of size 8 at 0x603000748788 thread T0
#0 0x437dab in flow_grid_delete_child ../src/flowgrid.c:203
#1 0x41ee65 in taskbar_item_destroy ../src/taskbar.c:34
#2 0x41ef51 in taskbar_item_destroy_for_all ../src/taskbar.c:43
#3 0x426672 in wintree_window_delete ../src/wintree.c:112
#4 0x438bc4 in toplevel_handle_closed ../src/wayland.c:52
#5 0x7f4dda3fb94c (/usr/lib64/libffi.so.7+0x694c)
#6 0x7f4dda3faf47 (/usr/lib64/libffi.so.7+0x5f47)
#7 0x7f4ddbc99210 (/usr/lib64/libwayland-client.so.0+0xa210)
#8 0x7f4ddbc959a9 (/usr/lib64/libwayland-client.so.0+0x69a9)
#9 0x7f4ddbc9712b in wl_display_dispatch_queue_pending (/usr/lib64/libwayland-client.so.0+0x812b)
#10 0x7f4ddc21dfd3 (/usr/lib64/libgdk-3.so.0+0x70fd3)
#11 0x7f4ddc1e736f in gdk_display_get_event (/usr/lib64/libgdk-3.so.0+0x3a36f)
#12 0x7f4ddc21dcd1 (/usr/lib64/libgdk-3.so.0+0x70cd1)
#13 0x7f4ddbd3963a in g_main_context_dispatch (/usr/lib64/libglib-2.0.so.0+0x5563a)
#14 0x7f4ddbd398a7 (/usr/lib64/libglib-2.0.so.0+0x558a7)
#15 0x7f4ddbd3994e in g_main_context_iteration (/usr/lib64/libglib-2.0.so.0+0x5594e)
#16 0x7f4ddbf4cd1c in g_application_run (/usr/lib64/libgio-2.0.so.0+0xd8d1c)
#17 0x40b883 in main ../src/sfwbar.c:187
#18 0x7f4ddb0f001c in __libc_start_main (/lib64/libc.so.6+0x2401c)
#19 0x40ac09 in _start (/initrd/mnt/dev_save/micko/sfwbar-10/build/sfwbar+0x40ac09)
0x603000748788 is located 8 bytes inside of 24-byte region [0x603000748780,0x603000748798)
freed by thread T0 here:
#0 0x7f4ddcb0f4f7 in free (/usr/lib64/libasan.so.6+0xb14f7)
#1 0x7f4ddbd34ec9 in g_list_delete_link (/usr/lib64/libglib-2.0.so.0+0x50ec9)
previously allocated by thread T0 here:
#0 0x7f4ddcb0f7ef in __interceptor_malloc (/usr/lib64/libasan.so.6+0xb17ef)
#1 0x7f4ddbd3f4d8 in g_malloc (/usr/lib64/libglib-2.0.so.0+0x5b4d8)
SUMMARY: AddressSanitizer: heap-use-after-free ../src/flowgrid.c:203 in flow_grid_delete_child
Shadow bytes around the buggy address:
0x0c06800e10a0: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
0x0c06800e10b0: fd fd fa fa fd fd fd fd fa fa 00 00 00 fa fa fa
0x0c06800e10c0: 00 00 00 fa fa fa 00 00 00 fa fa fa fd fd fd fd
0x0c06800e10d0: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
0x0c06800e10e0: fd fd fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa
=>0x0c06800e10f0: fd[fd]fd fa fa fa fd fd fd fd fa fa fd fd fd fd
0x0c06800e1100: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
0x0c06800e1110: fd fa fa fa fd fd fd fd fa fa fd fd fd fd fa fa
0x0c06800e1120: 00 00 00 00 fa fa fd fd fd fa fa fa fd fd fd fd
0x0c06800e1130: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
0x0c06800e1140: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==4008==ABORTING
Looks like a race condition in cleanup of taskbar items. Can you please check the latest git?
Looking good in initial tests. Closing the issue for now. Thank you.
Thank you for flagging these. I'm working on a major refactoring of a gui code, and certainly appreciate flagging any bugs that may arise in the process.
No problem at all. :smile: Still working well so far.
I landed a major rewrite of the widget system. Just wanted to check if everything still works ok with your config? Btw, you can in theory now merge your bar and launcher configs into a single config file (not sure it's worth it, other than saving some resources).
Also, would you mind sharing your pupnet.widget? Curious how you go about checking network status.
I can check on the weekend, a bit busy. However I'll post the widget now.
#!/bin/bash
# get network stuff
V=''
i=0
while read a b c d e f g h ; do
case $a in
[0-9]*)echo $h > /tmp/net_stats;;
esac
i=$(($i + 1))
[ $i -ge 3 ] && break
done <<<$(busybox route -n)
iface=$(cat /tmp/net_stats)
case $iface in
lo)ipaddr=$(busybox ifconfig $iface | grep -m1 'inet' | grep -o '127.*Mask' | sed 's/ Mask//')
V=pnot; echo -n "$V $iface none $ipaddr" > /tmp/net_stats0 ;;
u*)ipaddr=$(busybox ifconfig $iface | grep -o 'inet addr.*Bc' | sed -e 's/ Bc//' -e 's/inet addr://')
V=pcell; echo -n "$V $iface usb $ipaddr" > /tmp/net_stats0 ;;
*)read discard essid <<<$(iwconfig $iface | grep -o 'ESSID.*$'|tr '"' ' ')
ipaddr=$(busybox ifconfig $iface | grep -o 'inet addr.*Bc' | sed -e 's/ Bc//' -e 's/inet addr://')
[ -n "$essid" ] && essid=$(echo $essid | sed 's/ /_/g')
[ -n "$essid" ] && (V=pwifi; echo -n "$V $iface $essid $ipaddr" > /tmp/net_stats0) || \
(V=pwired; echo -n "$V $iface wired $ipaddr" > /tmp/net_stats0);;
esac
read V x y z </tmp/net_stats0
STATS="$x $y $z"
echo $V
echo "$STATS" > /tmp/net_stats
scanner {
# network
exec("get_net_stats") {
Icon = ReGex("([a-z]*[a-z])")
}
file("/tmp/net_stats") {
Tip = Grab()
}
}
layout {
image {
value = Pad(Icon,4)
interval = 3000
action = "defaultconnect"
tooltip = Pad(Tip,-64)
css = "* { min-height: 24px; min-width: 24px; padding: 4px; }"
}
}
The script is very basic and not portable as it uses busybox
but would be fairly trivial to replicate the output using other utilities and/or convert to ipv6. The icons are custom (and unique) and reside in /usr/share/icoms/hicolor/scalable/apps
but standard icons from any theme could be used.
Just tested my configs with latest (4 hours ago) and all working well with no errors or warnings. :smiley:
Just for your interest here is my temperature widget/script
scanner {
# cpu temp
exec("temp-icon.sh") {
TFile = Grab()
TTip = ReGex("([0-9]*[0-9])")
}
}
layout {
image {
value = Str(TFile,0)
interval = 2000
tooltip = Str(TTip,0)+"°C CPU temperature"
action = "lxtask"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
#!/bin/sh
TEMPDIR=$HOME/.config/sfwbar
[ -d "$TEMPDIR" ] || mkdir -p $TEMPDIR
# load module
for i in coretemp k10temp k8temp ; do
lsmod | grep -q $i || modprobe $i >/dev/null 2>&1
done
MOD=$(find -L /sys/class/hwmon/hwmon* -maxdepth 1 -type f -name 'name' | xargs cat | grep 'temp')
TEMPPATH=''
for i in $(find -L /sys/class/hwmon/hwmon* -maxdepth 1 -type f -name 'name') ; do
TEMPPATH=$i; cat $i | grep "$MOD" && break
done
TEMPPATH=${TEMPPATH/name/}
[ -e "${TEMPPATH}temp1_input" ] && T=$(cat ${TEMPPATH}temp1_input) || exit
temp2svg() {
# $1 is temp
fnt=18
if [ $1 -ge 100 ]; then
fnt=13
fi
if [ $1 -le 20 ]; then
r0=0;g0=$((0 * 10));b0=200
r1=0;g1=$((0 * 74 / 10));b1=148
elif [ $1 -gt 20 ] && [ $1 -le 40 ]; then
r0=0;g0=$(($(($1 - 20)) * 10));b0=200
r1=0;g1=$(($(($1 - 20)) * 74 / 10));b1=148
elif [ $1 -gt 40 ] && [ $1 -le 60 ]; then
r0=0;g0=200;b0=$(($((60 - $1)) * 10))
r1=0;g1=148;b1=$(($((60 - $1)) * 74 / 10))
elif [ $1 -gt 60 ] && [ $1 -le 80 ]; then
r0=$(($(($1 - 60)) * 10));g0=200;b0=0
r1=$(($(($1 - 60)) * 74 / 10));g1=148;b1=0
elif [ $1 -gt 80 ] && [ $1 -le 100 ]; then
r0=200;g0=$(($((100 - $1)) * 10));b0=0
r1=148;g1=$(($((100 - $1)) * 74 / 10));b1=0
elif [ $1 -gt 100 ] && [ $1 -le 120 ]; then
r0=200;g0=0;b0=$(($(($1 - 100)) * 10));
r1=148;g1=0;b1=$(($(($1 - 100)) * 74 / 10));
elif [ $1 -gt 120 ]; then
exit
fi
rm -f $TEMPDIR/[0-9][0-9].svg
rm -f $TEMPDIR/1[0-9][0-9].svg
cat > $TEMPDIR/${1}.svg <<E
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="24" width="24" viewBox="0 0 32 32">
<style>
.heavy { font: normal ${fnt}px sans; fill: #222222;}
</style>
<defs>
<linearGradient id="G0" gradientTransform="rotate(45)">
<stop offset="30%" stop-color="rgba($r0, $g0, $b0, 0.5)" />
<stop offset="70%" stop-color="rgba($r1, $g1, $b1, 0.5)" />
</linearGradient>
</defs>
<path style="fill:url(#G0);" d="m 4,0 24,0 a 4 4 0 0 1 4 4 l 0, 20 a 4 4 0 0 1 -4 4 l -24,0 a -4 -4 0 0 1 -4 -4 l 0,-20 a 4 4 0 0 1 4 -4 z"/>
<path style="fill:#222222;" d="m 28,4 a 3 3 0 1 0 0 6 a 3 3 0 1 0 0 -6 z m 0 1.5 a 1.5 1.5 0 1 1 0 3 a 1.5 1.5 0 1 1 0 -3 z"/>
<text x="1" y="22" class="heavy">$1</text>
</svg>
E
}
Temp=$(($T / 1000))
temp2svg $Temp
echo ${Temp}.svg
..and battery
scanner {
# battery
exec("powerapplet.sh") {
BFile = Grab()
BTip = Grab()
}
}
layout {
image {
value = "bat"+Str(BFile,0)+".svg"
interval = 10000
tooltip = Str(BTip,0)+"% Charged"
action = "powerapplet.sh s"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
#!/bin/bash
export TEMPDIR=$HOME/.config/sfwbar
[ -d "$TEMPDIR" ] || mkdir -p $TEMPDIR
export BATDIR=$(find -L /sys/class/power_supply -maxdepth 1 -type d -name 'BAT*')
[ -z "$BATDIR" ] && echo 'no battery' && exit # no battery
export CHHIGH="rgb(80,110,255)" # high charging blue
export DISHIGH="rgb(255,160,125)" # high discharging orange
export CHLOW="rgb(204,80,255)" # low charging purple
export DISLOW="rgb(255,91,71)" # low discharging red
export SYMBOLP='<path style="fill:#FFF152;stroke:#000" d="m 56 33 25 0 -13 35 11 -4 -25 38 7 -38 -11 6 z"/>'
export SYMBOLM='<path style="fill:#BB0000;stroke:none" d="m 50 60 28 0 0 8 -28 0 z"/>'
############################ functions #############################
paint_icon() {
STATE=$1 PERCENT=$2
if [ $STATE -eq 1 ] ; then
if [ $PERCENT -le 15 ] ; then
RGB=$CHLOW
else
RGB=$CHHIGH
fi
PLUS_OR_MINUS="$SYMBOLP" # '+'
else
if [ $PERCENT -le 15 ] ; then
RGB=$DISLOW
else
RGB=$DISHIGH
fi
PLUS_OR_MINUS="$SYMBOLM" # '-'
fi
GRAD1=$((90 - $PERCENT))
GRAD2=$((100 - $PERCENT))
if [ $GRAD1 -le 0 ] ; then
GRAD1=0
fi
rm -f $TEMPDIR/bat*.svg
cat > $TEMPDIR/bat${2}.svg <<_E
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 128 128">
<defs>
<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="${GRAD1}%" style="stop-color:rgb(150,150,150);stop-opacity:1" />
<stop offset="${GRAD2}%" style="stop-color:$RGB;stop-opacity:1" />
</linearGradient>
</defs>
<path style="fill:#232323;stroke:none" d="m 50 14 a 6 6 0 0 0 6 -6 l 16 0 a 6 6 0 0 0 6 6 z"/>
<path style="fill:url(#grad2);stroke:#232323;stroke-width:2" d="m 42 14 44 0 a 10 10 0 0 1 10 10 l 0 80 a 10 10 0 0 1 -10 10 l -44 0 a 10 10 0 0 1 -10 -10 l 0 -80 a 10 10 0 0 1 10 -10 z"/>
$PLUS_OR_MINUS
</svg>
_E
}
splash() {
ico=$(ls $TEMPDIR | grep '^bat')
gtkdialog-splash -font mono -fontsize 12 -icon ${TEMPDIR}/$ico -icon_width 60 -title -bg "thistle" -close box -text \
"$(cd $BATDIR ; for i in * ; do [ "$i" = 'uevent' ] && continue; [ -d "$i" ] && continue; echo -n "${i}: " && cat $i ; done)" &
}
main() {
FULL=$(find -L $BATDIR -maxdepth 1 -type f -name '*_full' | xargs cat)
NOW=$(find -L $BATDIR -maxdepth 1 -type f -name '*_now' |grep -E 'charge|energy' | xargs cat)
STATE=$(find -L $BATDIR -maxdepth 1 -type f -name 'status' | xargs cat)
if [ "$STATE" = "Full" ]; then
batpercent=100
charging=1
charged=1
else
charged=0;
if [ "$STATE" = "Charging" ]; then
charging=1
else
charging=0
fi
batpercent=$(($NOW * 100 / $FULL))
fi
paint_icon $charging $batpercent
case $charging in
1)
case $charged in
1)state="charged" ;;
0)state="charging" ;;
esac
;;
0)state="discharging"
;;
esac
paint_icon $charging $batpercent
echo ${batpercent}
}
export -f paint_icon splash main
######################### end functions ###########################
######################### main ###########################
case $1 in
s) splash ;;
*) main ;;
esac
######################### end main ###########################
Of course some puppy-isms in there (gtkdialog-splash
), but can easy be replaced with xmessage
or gxmessage
.
Interesting! My goal is to get to a point where most useful taskbar items can be implemented without need for scripts (launching scripts repeatedly carries a lot of overhead). Looking at the attachments, the battery widget can probably be implemented with the current functionality.
Battery would be trickier, but building svg on the fly is pretty cool. I need to look into adding functionality to source an image from svg data string. I think the construction of the actual svg string can already be implemented using the config expressions.
The network support is alltogether different. Since the necessary data can't be obtained from /proc or /sys files, it really would require a solution in code (and a lot of it is OS dependent). I think for the future versions, I'll look to implement dynamically loadable modules for things like network and audio controls. This way, we'll be able to make these features optional both at build time and at run time.
Adding support for loading svg's from config strings turned out to be trivial (15 lines of code). Here's how temperature widget looks in pure config language:
scanner {
file("/sys/class/hwmon/hwmon*/temp1_input") {
CPUTemp = Grab(First)
}
}
define fnt = If(CPUTemp >= 100,13,18)
define r0 = Str(If(CPUTemp>80, 200, If(CPUTemp>60, (CPUTemp-60)*10, 0)),0)
define r1 = Str(0.74 * Val(r0),0);
define g0 = Str(If(CPUTemp>100, 0, If(CPUTemp>80, (100-CPUTemp)*10,
If( CPUTemp>40, 200, If( CPUTemp>20, (CPUTemp - 20)*10, 0 )))),0)
define g1 = Str(0.74 * Val(g0),0)
define b0 = Str(If(CpuTemp>100, (CPUTemp - 100)*10, If( CPUTemp > 60, 0,
If( CPUTemp > 40, ( 60 - CPUTemp)*10, 200))),0)
define b1 = Str(0.74 * Val(b0),0)
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="24" width="24" viewBox="0 0 32 32">
<style>
.heavy { font: normal '+fnt+'px sans; fill: #222222;}
</style>
<defs>
<linearGradient id="G0" gradientTransform="rotate(45)">
<stop offset="30%" stop-color="rgba(' + r0 + ', ' + g0 + ', ' + b0 + ', 0.5)" />
<stop offset="70%" stop-color="rgba(' + r1 + ', ' + g1 + ', ' + b1 + ', 0.5)" />
</linearGradient>
</defs> <path style="fill:url(#G0);" d="m 4,0 24,0 a 4 4 0 0 1 4 4 l 0, 20 a 4 4 0 0 1 -4 4 l -24,0 a -4 -4 0 0 1 -4 -4 l 0,-20 a 4 4 0 0 1 4 -4 z"/>
<path style="fill:#222222;" d="m 28,4 a 3 3 0 1 0 0 6 a 3 3 0 1 0 0 -6 z m 0 1.5 a 1.5 1.5 0 1 1 0 3 a 1.5 1.5 0 1 1 0 -3 z"/>
<text x="1" y="22" class="heavy">20</text>
</svg>'
layout {
image {
value = svg
interval = 2000
tooltip = Str(CPUTemp,0) + "°C CPU temperature"
action = "lxtask"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
Adding support for loading svg's from config strings turned out to be trivial (15 lines of code). Here's how temperature widget looks in pure config language:
That is cool! I'm still learning the config language but each config you post I learn a bit more. Thanks!
Battery and temperature are a bit tricky with a all the different hardware out there. That's why I try to find the appropriate files with sane values. My test beds are a ryzen 5 home made system and a dell e7270 (intel skylake iirc). When I get time I want to get my raspberry pi 4 running with wayland and that is different again.
These are some great scripts, @01micko love how you generate the SVGs manually.
Likely nothing new for either of you but if executing external commands is fine this might be an generic alternative for some systems: upower -i /org/freedesktop/UPower/devices/battery_BAT0
(also provides an appropriate icon-name) and similar for temperatures via sensors
.
Just curious, is it possible with sfwbar to execute a process once and then just update when that process produces new output (e.g. via POLLIN on the subprocess stdout FD)? That could prevent rapidly re-executing scripts that are only doing file based actions themselves and also allows the scripts to define their own update interval instead of hard-coding it in a config.
You can use ExecClient scanner source to execute an external program once and then poll it for updates. Every time the output is ready, the scanner will update the variables and will emit a trigger. You can link a widget to update on a trigger (rather than an interval). This way you only update the gui whenever new information comes in.
On Fri, 15 Jul 2022, 22:53 Consolatis, @.***> wrote:
These are some great scripts, @01micko https://github.com/01micko love how you generate the SVGs manually.
Likely nothing new for either of you but if executing external commands is fine this might be an generic alternative for some systems: upower -i /org/freedesktop/UPower/devices/battery_BAT0 (also provides an appropriate icon-name) and similar for temperatures via sensors.
Just curious, is it possible with sfwbar to execute a process once and then just update when that process produces new output (e.g. via POLLIN on the subprocess stdout FD)? That could prevent rapidly re-executing scripts that are only doing file based actions themselves and also allows the scripts to define their own update interval instead of hard-coding it in a config.
— Reply to this email directly, view it on GitHub https://github.com/LBCrion/sfwbar/issues/32#issuecomment-1185974793, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASHPFFEU4MGPQRB4S73V6PLVUHMVJANCNFSM5ZZVHLPA . You are receiving this because you commented.Message ID: @.***>
These are some great scripts, @01micko love how you generate the SVGs manually.
Thanks!
The battery thing started out as powerapplet_tray.c
just almost straight copy/pasted with a few mods to shell! I could have written that routine in cairo
but svg
is quite simple and these days gtk does a good job with svg with little overhead. Anyway, GtkStatusIcon
has been deprecated a long time now and is just about dead.
How about something like this for the battery? The below setup calls the script once to build the scanner with correct filenames and then never calls the script again (unless the user clicks on the icon):
powerapplet.sh
#!/bin/sh
BATDIR=$(find -L /sys/class/power_supply -maxdepth 1 -type d -name 'BAT*')
[ -z "$BATDIR" ] && echo 'no battery' && exit # no battery
case $1 in
s)
# Do something useful here
;;
*)
FULL=$(find -L $BATDIR -maxdepth 1 -type f -name '*_full')
NOW=$(find -L $BATDIR -maxdepth 1 -type f -name '*_now' |grep -E 'charge|energy')
STATE=$(find -L $BATDIR -maxdepth 1 -type f -name 'status')
echo "scanner {
file(\"$FULL\") { BatTotal = Grab(First) }
file(\"$NOW\") { BatLeft = Grab(First) }
file(\"$STATE\") { BatState = RegEx(\"^(.*)$\",First) }
}"
;;
esac
powerapplet.widget
define batpercent = 0+If($BatState = "Full", 100, BatLeft / BatTotal * 100)
define charging = Val($BatState = "Full") | Val($BatState = "Charging")
define ChHigh = "Rgb(80,120,255)"
define DisHigh = "Rgb(80,120,255)"
define ChLow = "Rgb(204,80,255)"
define DisLow = "Rgb(255,91,71)"
define rgb = If(charging,
If(batpercent <= 15, ChLow, ChHigh),
If(batpercent <= 15, DisLow, DisHight ))
define sybolp = '<path style="fill:#FFF152;stroke:#000" d="m 56 33 25 0 -13 35 11 -4 -25 38 7 -38 -11 6 z"/>'
define sybolm = '<path style="fill:#BB0000;stroke:none" d="m 50 60 28 0 0 8 -28 0 z"/>'
define plus_or_minus = If( charging, sybolp, sybolm )
define grad1 = Str(If(90 - batpercent < 0, 0, 90 - batpercent),0)
define grad2 = Str(100 - batpercent,0)
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 128 128">
<defs>
<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="'+grad1+'%" style="stop-color:rgb(150,150,150);stop-opacity:1" />
<stop offset="'+grad2+'%" style="stop-color:'+rgb+';stop-opacity:1" />
</linearGradient>
</defs>
<path style="fill:#232323;stroke:none" d="m 50 14 a 6 6 0 0 0 6 -6 l 16 0 a 6 6 0 0 0 6 6 z"/>
<path style="fill:url(#grad2);stroke:#232323;stroke-width:2" d="m 42 14 44 0 a 10 10 0 0 1 10 10 l 0 80 a 10 10 0 0 1 -10 10 l -44 0 a 10 10 0 0 1 -10 -10 l 0 -80 a 10 10 0 0 1 10 -10 z"/>
'+plus_or_minus+'
</svg>'
layout {
image {
value = svg
interval = 100
tooltip = Str(batpercent,0)+"$ Charged"
action = "./powerapplet.sh s"
action[0] = PipeRead "./powerapplet.sh"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
I'll try the battery but the following will work perfectly for any temp 0 - 199 degrees.
scanner {
file("/sys/class/hwmon/hwmon*/temp1_input") {
CPUTemp = ReGex("(1?[0-9][0-9])")
}
}
define fnt = If(CPUTemp >= 100,13,18)
define r0 = Str(If(CPUTemp>80, 200, If(CPUTemp>60, (CPUTemp-60)*10, 0)),0)
define r1 = Str(0.74 * Val(r0),0);
define g0 = Str(If(CPUTemp>100, 0, If(CPUTemp>80, (100-CPUTemp)*10,
If( CPUTemp>40, 200, If( CPUTemp>20, (CPUTemp - 20)*10, 0 )))),0)
define g1 = Str(0.74 * Val(g0),0)
define b0 = Str(If(CpuTemp>100, (CPUTemp - 100)*10, If( CPUTemp > 60, 0,
If( CPUTemp > 40, ( 60 - CPUTemp)*10, 200))),0)
define b1 = Str(0.74 * Val(b0),0)
define t0 = Str(CPUTemp,0)
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="24" width="24" viewBox="0 0 32 32">
<style>
.heavy { font: normal '+fnt+'px sans; fill: #222222;}
</style>
<defs>
<linearGradient id="G0" gradientTransform="rotate(45)">
<stop offset="30%" stop-color="rgba(' + r0 + ', ' + g0 + ', ' + b0 + ', 0.5)" />
<stop offset="70%" stop-color="rgba(' + r1 + ', ' + g1 + ', ' + b1 + ', 0.5)" />
</linearGradient>
</defs> <path style="fill:url(#G0);" d="m 4,0 24,0 a 4 4 0 0 1 4 4 l 0, 20 a 4 4 0 0 1 -4 4 l -24,0 a -4 -4 0 0 1 -4 -4 l 0,-20 a 4 4 0 0 1 4 -4 z"/>
<path style="fill:#222222;" d="m 28,4 a 3 3 0 1 0 0 6 a 3 3 0 1 0 0 -6 z m 0 1.5 a 1.5 1.5 0 1 1 0 3 a 1.5 1.5 0 1 1 0 -3 z"/>
<text x="1" y="22" class="heavy">' + t0 + '</text>
</svg>'
layout {
image {
value = svg
interval = 2000
tooltip = Str(CPUTemp,0) + "°C CPU temperature"
action = "lxtask"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
Battery works but there is a problem with the arithmetic and gradients don't show. - sign is adding instead of subtracting in grad1
and grad2
.
define grad1 = Str(If(90 - batpercent < 0, 0, 90 - batpercent),0)
define grad2 = Str(100 - batpercent,0)
Config hacked to show subtraction error in tooltip
define batpercent = 0+If($BatState = "Full", 100, BatLeft / BatTotal * 100)
define charging = Val($BatState = "Full") | Val($BatState = "Charging")
define ChHigh = "rgb(80,120,255)"
define DisHigh = "rgb(80,120,255)"
define ChLow = "rgb(204,80,255)"
define DisLow = "rgb(255,91,71)"
define rgb = If(charging,
If(batpercent <= 15, ChLow, ChHigh),
If(batpercent <= 15, DisLow, DisHigh ))
define sybolp = '<path style="fill:#FFF152;stroke:#000" d="m 56 33 25 0 -13 35 11 -4 -25 38 7 -38 -11 6 z"/>'
define sybolm = '<path style="fill:#BB0000;stroke:none" d="m 50 60 28 0 0 8 -28 0 z"/>'
define plus_or_minus = If( charging, sybolp, sybolm )
define grad1 = Str(If(90 - batpercent < 0, 0, 90 - batpercent),0)
define grad2 = Str(100 - batpercent,0)
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="28" width="28" viewBox="0 0 128 128">
<defs>
<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="'+grad1+'%" style="stop-color:rgb(150,150,150);stop-opacity:1" />
<stop offset="'+grad2+'%" style="stop-color:rgb(80,120,255);stop-opacity:1" />
</linearGradient>
</defs>
<path style="fill:#232323;stroke:none" d="m 50 14 a 6 6 0 0 0 6 -6 l 16 0 a 6 6 0 0 0 6 6 z"/>
<path style="fill:url(#grad2);stroke:#232323;stroke-width:2" d="m 42 14 44 0 a 10 10 0 0 1 10 10 l 0 80 a 10 10 0 0 1 -10 10 l -44 0 a 10 10 0 0 1 -10 -10 l 0 -80 a 10 10 0 0 1 10 -10 z"/>
'+plus_or_minus+'
</svg>'
layout {
image {
value = svg
interval = 1000
tooltip = Str(batpercent,0)+"% Charged "+Pad(grad1,0)+" "+Pad(grad2,0)
action = "powerapplet2.sh s"
action[0] = PipeRead "powerapplet2.sh"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
Well, that was rather silly of me, the first line of the widget file should be:
define batpercent = (0+If($BatState = "Full", 100, BatLeft / BatTotal * 100))
Without the outer parenthesis, the grad expressions expand to 90-0+If(...), and we of course want 90-(0+If(...))
We are all good now :smiley:
define batpercent = (0 + If($BatState = "Full", 100, BatLeft / BatTotal * 100))
define charging = Val($BatState = "Full") | Val($BatState = "Charging")
define ChHigh = "rgb(80,120,255)"
define DisHigh = "rgb(255,160,125)"
define ChLow = "rgb(204,80,255)"
define DisLow = "rgb(255,91,71)"
define rgb = If(charging,
If(batpercent <= 15, ChLow, ChHigh),
If(batpercent <= 15, DisLow, DisHigh ))
define sybolp = '<path style="fill:#FFF152;stroke:#000" d="m 56 33 25 0 -13 35 11 -4 -25 38 7 -38 -11 6 z"/>'
define sybolm = '<path style="fill:#BB0000;stroke:none" d="m 50 60 28 0 0 8 -28 0 z"/>'
define plus_or_minus = If( charging, sybolp, sybolm )
define grad1 = Str(If(90 - batpercent < 0, 0, 90 - batpercent),0)
define grad2 = Str(100 - batpercent,0)
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="28" width="28" viewBox="0 0 128 128">
<defs>
<linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="'+grad1+'%" style="stop-color:rgb(150,150,150);stop-opacity:1" />
<stop offset="'+grad2+'%" style="stop-color:' + rgb + ';stop-opacity:1" />
</linearGradient>
</defs>
<path style="fill:#232323;stroke:none" d="m 50 14 a 6 6 0 0 0 6 -6 l 16 0 a 6 6 0 0 0 6 6 z"/>
<path style="fill:url(#grad2);stroke:#232323;stroke-width:2" d="m 42 14 44 0 a 10 10 0 0 1 10 10 l 0 80 a 10 10 0 0 1 -10 10 l -44 0 a 10 10 0 0 1 -10 -10 l 0 -80 a 10 10 0 0 1 10 -10 z"/>
'+plus_or_minus+'
</svg>'
layout {
image {
value = svg
interval = 1000
tooltip = Str(batpercent,0)+"% Charged"
action = "powerapplet2.sh s"
action[0] = PipeRead "powerapplet2.sh"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
And that green cylinder is a very simple disk usage widget.. again with puppyisms but the buttons could be used to call anything else, even xterm -e "df /"
scanner {
exec("df -BM /|tail -n1|awk '{print $5}'|sed 's/%//'") {
Usage = Grab()
}
}
define Low = "rgb(255,27,0)"
define Medium = "rgb(255,183,0)"
define High = "rgb(60,199,61)"
define Col = If(Usage <= 50,High,If(Usage >= 80,Low,Medium))
define Hgt = If(Usage <= 25,20,
If(Usage <= 50,41,
If(Usage <= 75,50,
If(Usage < 85,66,80))))
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 100 100">
<ellipse cx="50" cy="20" rx="35" ry="10" style="stroke-width:5;stroke:#222222;fill:none;"/>
<ellipse cx="50" cy="80" rx="35" ry="10" style="stroke-width:2;stroke:#222222;fill:'+Col+';fill-opacity:0.5;"/>
<path style="fill:'+Col+';fill-opacity:0.8;" d="m 15,'+Hgt+' c 0,-6 16,-10 36,-10 18,0 34,4 34,10 l 0,31 C 82,86 69,90 52,90 36,90 18,87 15,81 z"/>
<ellipse cx="50" cy="65" rx="35" ry="10" style="stroke-width:2;stroke:'+Col+';fill:none;"/>
<path style="fill:none;stroke:'+Col+';stroke-width:2" d="m 15,66 c 6,6 21,10 36,10 15,0 28,-3 34,-9"/>
<path style="fill:none;stroke:#222222;stroke-width:3.5" d="m 15,21 c 0,0 0,0 0,61 7,6 22,8 37,8 14,0 27,-2 33,-9 0,0 0,-58 0,-60"/>
</svg>'
layout {
image {
value = svg
interval = 10000
action[1] = "partview"
action[3] = "resizepfile.sh"
tooltip = Str(Usage,0)+"% disk usage"
css = "* { min-height: 24px; min-width: 24px; padding: 4px; }"
}
}
You can replace your scanner section with:
Usage = Disk("/","%used")
This will use ioctl to check disk usage. The number reported will differ slightly from df output, since df includes reserved space into Use%.
I see, but you need to you fix the docs as "%used" isn't mentioned. Works well. Thanks.
sfwbar.rst
Disk | get disk utilization data. You need to specify a mount point as a first argument and data field as a second. The supported data fields are "total", "avail", "free", "%avail", "%free". Returns a number. |
---|
Actually, the widget is now much more informative with minimal effort.
define Usage = Disk("/","%used")
define Tot = Disk("/","total")
define Avail = Disk("/","avail")
define Low = "rgb(255,27,0)"
define Medium = "rgb(255,183,0)"
define High = "rgb(60,199,61)"
define Col = If(Usage <= 50,High,If(Usage >= 80,Low,Medium))
define Hgt = If(Usage <= 25,20,
If(Usage <= 50,41,
If(Usage <= 75,50,
If(Usage < 85,66,80))))
define svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 100 100">
<ellipse cx="50" cy="20" rx="35" ry="10" style="stroke-width:5;stroke:#222222;fill:none;"/>
<ellipse cx="50" cy="80" rx="35" ry="10" style="stroke-width:2;stroke:#222222;fill:'+Col+';fill-opacity:0.5;"/>
<path style="fill:'+Col+';fill-opacity:0.8;" d="m 15,'+Hgt+' c 0,-6 16,-10 36,-10 18,0 34,4 34,10 l 0,31 C 82,86 69,90 52,90 36,90 18,87 15,81 z"/>
<ellipse cx="50" cy="65" rx="35" ry="10" style="stroke-width:2;stroke:'+Col+';fill:none;"/>
<path style="fill:none;stroke:'+Col+';stroke-width:2" d="m 15,66 c 6,6 21,10 36,10 15,0 28,-3 34,-9"/>
<path style="fill:none;stroke:#222222;stroke-width:3.5" d="m 15,21 c 0,0 0,0 0,61 7,6 22,8 37,8 14,0 27,-2 33,-9 0,0 0,-58 0,-60"/>
</svg>'
layout {
image {
value = svg
interval = 10000
action[1] = "partview"
action[3] = "resizepfile.sh"
tooltip = Str(Usage,0)+"% disk usage\nTotal: "+Str(Tot/1048576,0)+"MB\nAvailable: "+Str(Avail/1048576,0)+"MB"
css = "* { min-height: 24px; min-width: 24px; padding: 4px; }"
}
}
I fixed a bug in scaling code for inline svg loader. Just a heads up in case it breaks anything in your config. Inline svgs should now respect css min-width / min-height. Also, what do you do for the volume widget? I tried to implement an optimized volume control/tracker in wbar.config, bu would be interesting to see how you approached it.
I fixed a bug in scaling code for inline svg loader. Just a heads up in case it breaks anything in your config. Inline svgs should now respect css min-width / min-height.
Thanks, I'll check that out soon.
Also, what do you do for the volume widget? I tried to implement an optimized volume control/tracker in wbar.config, bu would be interesting to see how you approached it.
We use gtkdialog
.
We recently introduced gtk-layer-shell
support to gtkdialog
so it is quite useful with wayland
. It's fun for our users too, who may not be able to comprehend C
, C++
, python
or perl
but have a basic grasp of shell scripting enabling them to create a simple or complex GUI.
Latest main is working fine for me.
Cool. Thank you for checking.
Somewhat unrelated. I just noticed that on my laptop, once, the battery is charged, the status goes to "Unknown" rather than "Full", so I amended, the charging parameter to !Val($BatState = "Discharging")
Pretty amazed that this config works well:
# stock puppy sfwbar.config
menu("winops") {
item("focus", Focus );
item("close", Close );
item("(un)minimize", Function "ToggleMinimize" );
item("(un)maximize", Function "ToggleMaximize" );
}
function("ToggleMinimize") {
[!Minimized] Minimize
[Minimized] UnMinimize
}
function("ToggleMaximize") {
[!Maximized] Maximize
[Maximized] UnMaximize
}
function("SfwbarInit") {
SetLayer "panel", "bottom"
SetMonitor "panel", "DVI-D-1"
SetExclusiveZone "panel", "1"
SetLayer "launcher", "bottom"
SetMonitor "launcher", "DVI-D-1"
SetBarSize "launcher", "160"
}
# work arounds for vivaldi/opera icons .. there could be more
MapAppId ".*Vivaldi$", "vivaldi"
MapAppId ".*Opera$", "opera"
# Panel layout
layout "panel "{
style = frame
button {
value = "/usr/share/pixmaps/puppy/puppy.svg"
action = "killall -usr1 altf1d" # launch menu on click
tooltip = "Launch menu"
css = "* { min-height: 24px; min-width: 48px; }"
}
image {
value = "terminal"
action = "defaultterminal"
tooltip = "Launch terminal"
css = "* { min-height: 24px; min-width: 24px; padding: 5px; }"
}
image {
value = "browser"
action = "defaultbrowser"
tooltip = "Launch browser"
css = "* { min-height: 24px; min-width: 24px; padding: 5px; }"
}
image {
value = "directory"
action = "defaultfilemanager"
tooltip = "Launch file manager"
css = "* { min-height: 24px; min-width: 24px; padding: 5px; }"
}
taskbar {
rows = 1
css = "* { -GtkWidget-hexpand: true; }" # stretch horizontally
icons = true
labels = true
action[3] = Menu "winops"
}
image {
value = "audio-volume-high"
action[1] = "ppavolume"
action[2] = "fix_sound_crash"
action[3] = "pavucontrol"
tooltip = "Volume control"
css = "* { min-height: 24px; min-width: 24px; padding: 4px; }"
}
include("includes.widget")
image {
value = "shutdown"
action = "logout_gui"
tooltip = "Logout"
css = "* { min-height: 24px; min-width: 24px; padding: 4px; }"
}
}
# Launcher layout
layout "launcher" {
style = frame
grid {
include("launcher.widget")
}
}
#CSS
window {
-GtkWidget-direction: top;
border-radius: 6px;
color: rgba(17, 17, 17, 0.73);
}
window#launcher {
-GtkWidget-direction: bottom;
border-radius: 6px;
background-color: rgba(17, 17, 17, 0.333);
}
button#taskbar_normal image, button#taskbar_active image, button#taskbar_normal:hover image {
background-color: rgba(0, 0, 0, 0.0);
min-width: 0.4cm;
min-height: 0.4cm;
}
button#taskbar_normal label, button#taskbar_active label, button#taskbar_normal:hover label {
background-color: rgba(0, 0, 0, 0.0);
-GtkWidget-vexpand: true;
padding-left: 0.5mm;
padding-top: 0px;
padding-bottom: 0px;
font: 10pt Sans;
}
button#taskbar_normal , button#taskbar_active , button#taskbar_normal:hover {
padding: 3px;
border: 0.5px;
}
button#pager_normal , button#pager_visible , button#pager_focused {
background-color: rgba(0, 0, 0, 0.0);
padding-left: 1.25mm;
padding-right: 1.25mm;
padding-top: 0.5mm;
padding-bottom: 0.5mm;
background-image: none;
border-radius: 0;
border-image: none;
font: 10pt Sans;
}
button#pager_focused {
background-color: #bbddff;
}
button#pager_preview {
background-color: rgba(0, 0, 0, 0.0);
background-image: none;
border-radius: 0;
border-image: none;
border-color: #000000;
border-width: 0.25mm;
color: #777777;
min-width: 5cm;
min-height: 1.4125cm;
}
button#taskbar_normal:hover {
background-color: #BF892B;
}
button#menu {
background-color: transparent;
border: 1px solid transparent;
padding: 3px;
}
grid#pager {
outline-color: #000000;
outline-style: dashed;
outline-width: 0.25mm;
}
grid#switcher_active *, grid#switcher_active, grid#switcher_active * * {
min-width: 0.5cm;
min-height: 0.5cm;
border-image: none;
padding: 1.25mm;
background-color: #bbddff;
border-radius: 1.25mm;
}
grid#switcher_normal *, grid#switcher_normal, grid#switcher_normal * * {
min-width: 0.5cm;
min-height: 0.5cm;
border-image: none;
padding: 0.5mm;
}
window#switcher {
border-style: solid;
border-width: 0.25mm;
border-color: #000000;
border-radius: 1.25mm;
padding: 1.25mm;
-GtkWidget-hexpand: true;
}
grid#switcher {
border-radius: 1.25mm;
padding: 1.25mm;
}
image#tray_active, image#tray_passive, image#tray_attention {
min-width: 1cm;
min-height: 1cm;
}
progressbar {
padding-left: 0.25mm;
padding-right: 0.25mm;
-GtkWidget-vexpand: true;
-GtkWidget-direction: top;
}
progress, trough {
border-radius: 0;
border-color: #9c9c9c;
}
progress {
border-style: outset;
min-width: 2mm;
}
trough {
background-color: #a1a1a1;
border-style: inset;
min-height: 2.5mm;
min-width: 2.5mm;
}
grid#frame {
-GtkWidget-direction: bottom;
min-width: 1cm;
border-color: #9c9c9c;
border-style: groove;
border-width: 0.5mm;
padding-top: 0.25mm;
}
grid#layout {
padding: 0.25mm;
-GtkWidget-direction: right;
}
label#value {
min-width: 1cm;
-GtkWidget-hexpand: true;
-GtkWidget-align: 0.5;
}
image#value_icon {
padding: 0.1cm;
min-width: 16px;
min-height: 16px;
}
label#wifi {
min-height: 24px;
min-width: 24px;
font: 14pt Pupmoon;
padding: 5px;
color: #34A734;
}
label#wire {
min-height: 24px;
min-width: 24px;
font: 14pt Pupmoon;
padding: 5px;
}
button {
padding: 3px;
border-width: 0.5px;
border-radius: 6px;
}
layout {
css = "* { -GtkWidget-direction: right; }"
button {
value = "directory-home"
action = "defaultfilemanager"
tooltip = "File Manager"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
button {
value = "edit"
action = "defaulttexteditor"
tooltip = "Text Editor"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
button {
value = "browser"
action = "defaultbrowser"
tooltip = "Browser"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
button {
value = "mail"
action = "defaultemail"
tooltip = "Email"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
button {
value = "paint"
action = "defaultpaint"
tooltip = "Paint"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
button {
value = "terminal"
action = "defaultterminal"
tooltip = "Terminal"
css = "* { min-height: 36px; min-width: 36px; margin: 4px; }"
}
}
So what's your preference for where I post my configs? I could start a repo and post to my own or offer an 'extra-configs' PR if you want to include them here. Might be better if I host my own and you can link to it in README if you like.
That is some clean config, I like it.
I think the raw CSS part at the bottom of the config could be moved into another file and included, similar to launcher.widget
to get an even cleaner and self-explaining config file.
There's actually a couple of small mistakes in the top config. Easily fixed.
s/SetExclusiveZone "panel", "1"/SetExclusiveZone "panel", "32"/
s/"panel "/"panel" /
s/window {/window#panel {/
Hmmm.. this is nice - the extra configs can be anywhere! So long as you specify the path - relative or absolute works.
Wow. It's really nice to see a complete config like this. It shows that some of the features I've been adding over the last couple of years are actually useful. @01micko, I think it may be better to put this config into a separate repository and link it from the README. It uses quite a few puppy specific commands, so putting it separately would make it clear for users that it has dependencies other than those required by sfwbar. @Consolatis, you can actually put css into a separate fill with the same base name as the config (i.e. myconfig.config and myconfig.css) and sfwbar will automatically pick it up.
@LBCrion no problem at all. I'll initialise a repo soon.
@Consolatis, you can actually put css into a separate fill with the same base name as the config (i.e. myconfig.config and myconfig.css) and sfwbar will automatically pick it up.
By that rationale, I should (?) be able to rename my launcher.widget
to launcher.config
with necessary adjustments.
~$ sfwbar -d 2>&1 | grep include
22:21:41.58 include: sfwbar.config -> /root/.config/sfwbar/sfwbar.config
22:21:41.59 include: barlauncher.widget -> /root/.config/sfwbar/barlauncher.widget
22:21:41.62 include: includes.widget -> /root/.config/sfwbar/includes.widget
22:21:41.62 include: volume.widget -> /root/.config/sfwbar/volume.widget
22:21:41.62 include: firewall.widget -> /root/.config/sfwbar/firewall.widget
22:21:41.62 include: temp.widget -> /root/.config/sfwbar/temp.widget
22:21:41.63 include: pupnet.widget -> /root/.config/sfwbar/pupnet.widget
22:21:41.65 include: pupusage.widget -> /root/.config/sfwbar/pupusage.widget
22:21:41.65 include: clock.widget -> /root/.config/sfwbar/clock.widget
22:21:41.65 include: idle.widget -> /root/.config/sfwbar/idle.widget
22:21:41.65 include: logout.widget -> /root/.config/sfwbar/logout.widget
22:21:41.66 include: launcher.config -> /root/.config/sfwbar/launcher.config
Ouch. Looking at the code, it looks like the program no longer checks for .css file. I need to re-instate this functionality.
It should work now. You don't need to rename launcher.widget to launcher.config, sfwbar will pick up launcher.css either way.
Started on my separate repo for configs, but in the meantime here is my revised sound/volume widget for pulseaudio
scanner {
exec("pactl list sinks | grep -o 'Volume.*right' | grep -o '[0-9]*%.*\/' | sed 's#%.*##'") {
SoundState = Grab(first)
}
}
define muted = "audio-volume-muted"
define low = "audio-volume-low"
define medium = "audio-volume-medium"
define high = "audio-volume-high"
define SoundIcon = If(SoundState>100, high, If(SoundState>50, medium, If(SoundState>5, low, muted)))
layout {
image {
value = SoundIcon
interval = 600
tooltip = "Volume " + Str(SoundState * 2 / 3,0) + "%"
action[1] = "pavol.sh" # you can change this
action[3] = "pavucontrol"
css = "* { min-height: 28px; min-width: 28px; padding: 4px; }"
}
}
#!/bin/bash
# requires gtkdialog or falls back to pavucontrol
type gtkdialog >/dev/null 2>&1 || exec pavucontrol
#******************* functions *******************#
check_exit() { # kill gui on leave-notify-event
sleep 0.5
for i in $(busybox ps | grep -wF HSCALE | grep -o '[1-9][0-9]*'); do
kill -9 $i >/dev/null 2>&1
done
}
get_vol() { # get volume
pactl list sinks |\
grep -o 'Volume.*right'|grep -o '[0-9]*%.*\/'|sed 's/% \///'
}
set_vol() { # set volume
VAL=$1
pactl -- set-sink-volume 0 ${VAL}%
echo $VAL > /tmp/vol
}
find_color() {
printf "%d" "0x${1}"
}
find_opacity() {
DEC=$(printf "%d" "0x${1}")
OP=$(dc -e "$DEC 256 2 k / p")
echo "0${OP}"
}
export -f check_exit get_vol set_vol find_color find_opacity
#************************** theme *****************************#
OPT=''
CURTHEME=$(gsettings get org.gnome.desktop.interface gtk-theme | tr -d "'")
BCOL=$(grep -m1 'theme_bg_color' /usr/share/themes/$CURTHEME/gtk-3.0/gtk.css)
BCOL=${BCOL##*\ }
BCOL=${BCOL##*\#}
BCOL=${BCOL%%\;*}
BR=${BCOL:0:2}; BG=${BCOL:2:2}; BB=${BCOL:4:2};
BHR=$(find_color $BR)
BHG=$(find_color $BG)
BHB=$(find_color $BB)
BHO=0.85
# openbox border
if pidof labwc >/dev/null 2>&1 ; then
BD=$(grep 'window\.active\.border\.color' /usr/share/themes/$CURTHEME/openbox-3/themerc|cut -d' ' -f2)
BR=$(grep -o '<cornerRadius>.*[0-9]' ~/.config/labwc/rc.xml | tail -c2)
else
BD='#dddddd'
BR=2
fi
cat > /tmp/${0##*\/}.css <<_S
window {
background-color: rgba($BHR, $BHG, $BHB, $BHO);
border: 1px solid $BD;
border-radius: ${BR}px;
}
_S
#************************** main *****************************#
OPT="--styles=/tmp/${0##*\/}.css"
TGT="$(grep -n -m1 '\-GtkWidget-direction' $HOME/.config/sfwbar/sfwbar.config)"
TGT_LN=${TGT%%\:*}
TGT_STR="${TGT#*\ \ }"
echo $TGT_STR | grep -qo 'top' && POSITION=topright
echo $TGT_STR | grep -qo 'bottom' && POSITION=bottomright
CVOL=`get_vol`
export HSCALE='<window edge="'$POSITION'" layer="overlay">
<hbox>
<pixmap auto-refresh="true">
<height>20</height>
<input file icon="multimedia-volume-control"></input>
</pixmap>
<hscale width-request="375" height-request="40" \
range-min="0" range-max="150" range-step="0.5" value-pos="3" digits="2">
<default>'$CVOL'</default>
<variable>VOL</variable>
<action>set_vol ${VOL%\.*}</action>
<item>"0 |2|0"</item>
<item>"50 |2|50"</item>
<item>"100|2|100"</item>
<item>"150|2|150"</item>
<action signal="leave-notify-event">check_exit</action>
</hscale>
</hbox>
</window>'
gtkdialog -p HSCALE "$OPT" >/dev/null 2>&1
https://user-images.githubusercontent.com/1019119/185915854-8ff42d86-6ced-4f5f-900a-52b34f564e2f.mp4
Nice! How about this for a sound widget? It launches "pactl subscribe" to monitor volume changes and only refreshes the widget when it gets a signal from pactl subscribe process. This way, the widget can be responsive to volume changes without launching pactl over and over.
scanner { execClient("pactl subscribe","pactl") { SoundSink = RegEx("(sink)") } exec("pactl get-sink-volume @DEFAULT_SINK@") { SoundVolume = RegEx("right:[ ][0-9][/ ]([0-9])%") } } define SoundState = Val(If(SoundSink.count=0 & Cached(SoundVolume.count)>0, Cached(SoundVolume),SoundVolume)) define muted = "audio-volume-muted" define low = "audio-volume-low" define medium = "audio-volume-medium" define high = "audio-volume-high" define SoundIcon = If(SoundState>100, high, If(SoundState>50, medium, If(SoundState>5, low, muted)))
layout { image { value = SoundIcon trigger = "pactl" tooltip = "Volume " + Str(SoundState 2 / 3,0) + "%" action[1] = "pavol.sh" # you can change this action[3] = "pavucontrol" css = " { min-height: 28px; min-width: 28px; padding: 4px; }" } }
Can you try the latest git please? I you still get the error, try running "sfwbar -d -g channel", this should generate some (hopefully useful) debug info.
No bar appears if I use your pa config.
EDIT: by the way, no error messages or otherwise when there is no bar appearing either, so must be getting close.
~$ sfwbar -d -g channel
18:02:9.44 channel(out) 0x23f77a0, handle 11, readable 0, writable 8
18:02:9.44 channel(in) 0x2480900, handle 12, readable 4, writable 0
18:02:9.44 channel connection (nil)
18:02:9.54 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.54 channel connection (nil)
18:02:9.56 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.56 channel connection (nil)
18:02:9.57 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.57 channel connection (nil)
18:02:9.57 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.57 channel connection (nil)
18:02:9.58 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.58 channel connection (nil)
18:02:9.58 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.58 channel connection (nil)
18:02:9.59 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.59 channel connection (nil)
18:02:9.59 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.59 channel connection (nil)
18:02:9.60 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.60 channel connection (nil)
18:02:9.60 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.60 channel connection (nil)
18:02:9.60 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.60 channel connection (nil)
18:02:9.61 channel(out) 0x23f77a0, readable 0, writable 8, cond 1
18:02:9.61 channel connection (nil)
Does it keep printing these messages or does it just print this set an then sits there?
If it keeps printing, can you run it again with the latest git please? I added some more debug info generation.
It keeps printing.
Still no bar.
~$ sfwbar -d -g channel
06:09:51.91 channel(out) 0xc86db0, handle 11, readable 0, writable 8
06:09:51.91 channel(in) 0xc89da0, handle 12, readable 4, writable 0
06:09:51.91 channel connection (nil)
06:09:51.92 channel status 2
06:09:51.92 channel status 2
06:09:51.92 channel status 2
06:09:51.92 channel status 2
06:09:51.93 channel status 2
06:09:51.95 channel status 2
06:09:51.95 channel status 2
06:09:51.99 channel status 2
06:09:51.99 channel status 2
06:09:51.99 channel status 2
06:09:52.00 channel status 2
06:09:52.01 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.01 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.01 channel connection (nil)
06:09:52.01 channel status 3
06:09:52.02 channel status 2
06:09:52.02 channel status 2
06:09:52.02 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.02 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.02 channel connection (nil)
06:09:52.02 channel status 3
06:09:52.03 channel status 2
06:09:52.03 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.03 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.03 channel connection (nil)
06:09:52.03 channel status 3
06:09:52.04 channel status 2
06:09:52.04 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.04 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.04 channel connection (nil)
06:09:52.04 channel status 3
06:09:52.04 channel status 2
06:09:52.05 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.05 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.05 channel connection (nil)
06:09:52.05 channel status 3
06:09:52.05 channel status 2
06:09:52.05 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.05 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.05 channel connection (nil)
06:09:52.05 channel status 3
06:09:52.06 channel status 2
06:09:52.06 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.06 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.06 channel connection (nil)
06:09:52.06 channel status 3
06:09:52.06 channel status 2
06:09:52.06 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.06 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.06 channel connection (nil)
06:09:52.06 channel status 3
06:09:52.07 channel status 2
06:09:52.07 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.07 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.07 channel connection (nil)
06:09:52.07 channel status 3
06:09:52.08 channel status 2
06:09:52.08 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.08 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.08 channel connection (nil)
06:09:52.08 channel status 3
06:09:52.09 channel status 2
06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.09 channel connection (nil)
06:09:52.09 channel status 3
06:09:52.09 channel status 2
06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.09 channel connection (nil)
06:09:52.09 channel status 3
06:09:52.09 channel status 2
06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.09 channel connection (nil)
06:09:52.09 channel status 3
06:09:52.11 channel status 2
06:09:52.11 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.11 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.11 channel connection (nil)
06:09:52.11 channel status 3
06:09:52.11 channel status 2
06:09:52.11 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.11 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.11 channel connection (nil)
06:09:52.11 channel status 3
06:09:52.11 channel status 2
06:09:52.12 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.12 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.12 channel connection (nil)
06:09:52.12 channel status 3
06:09:52.12 channel status 2
06:09:52.12 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.12 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.12 channel connection (nil)
06:09:52.12 channel status 3
06:09:52.13 channel status 2
06:09:52.13 channel(out) 0xc86db0, readable 0, writable 8, cond 0
06:09:52.13 channel(in) 0xc89da0, readable 4, writable 0, cond 1
06:09:52.13 channel connection (nil)
06:09:52.13 channel status 3
06:09:52.13 channel status 2
This looks like pactl subscribe keeps sending new data. Can you try running pactl subscribe in a separate terminal and see if it keeps printing something while sfwbar is running?
On Tue, 30 Aug 2022, 21:12 Mick Amadio, @.***> wrote:
It keeps printing.
Still no bar.
~$ sfwbar -d -g channel 06:09:51.91 channel(out) 0xc86db0, handle 11, readable 0, writable 8 06:09:51.91 channel(in) 0xc89da0, handle 12, readable 4, writable 0 06:09:51.91 channel connection (nil) 06:09:51.92 channel status 2 06:09:51.92 channel status 2 06:09:51.92 channel status 2 06:09:51.92 channel status 2 06:09:51.93 channel status 2 06:09:51.95 channel status 2 06:09:51.95 channel status 2 06:09:51.99 channel status 2 06:09:51.99 channel status 2 06:09:51.99 channel status 2 06:09:52.00 channel status 2 06:09:52.01 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.01 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.01 channel connection (nil) 06:09:52.01 channel status 3 06:09:52.02 channel status 2 06:09:52.02 channel status 2 06:09:52.02 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.02 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.02 channel connection (nil) 06:09:52.02 channel status 3 06:09:52.03 channel status 2 06:09:52.03 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.03 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.03 channel connection (nil) 06:09:52.03 channel status 3 06:09:52.04 channel status 2 06:09:52.04 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.04 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.04 channel connection (nil) 06:09:52.04 channel status 3 06:09:52.04 channel status 2 06:09:52.05 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.05 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.05 channel connection (nil) 06:09:52.05 channel status 3 06:09:52.05 channel status 2 06:09:52.05 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.05 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.05 channel connection (nil) 06:09:52.05 channel status 3 06:09:52.06 channel status 2 06:09:52.06 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.06 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.06 channel connection (nil) 06:09:52.06 channel status 3 06:09:52.06 channel status 2 06:09:52.06 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.06 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.06 channel connection (nil) 06:09:52.06 channel status 3 06:09:52.07 channel status 2 06:09:52.07 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.07 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.07 channel connection (nil) 06:09:52.07 channel status 3 06:09:52.08 channel status 2 06:09:52.08 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.08 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.08 channel connection (nil) 06:09:52.08 channel status 3 06:09:52.09 channel status 2 06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.09 channel connection (nil) 06:09:52.09 channel status 3 06:09:52.09 channel status 2 06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.09 channel connection (nil) 06:09:52.09 channel status 3 06:09:52.09 channel status 2 06:09:52.09 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.09 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.09 channel connection (nil) 06:09:52.09 channel status 3 06:09:52.11 channel status 2 06:09:52.11 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.11 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.11 channel connection (nil) 06:09:52.11 channel status 3 06:09:52.11 channel status 2 06:09:52.11 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.11 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.11 channel connection (nil) 06:09:52.11 channel status 3 06:09:52.11 channel status 2 06:09:52.12 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.12 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.12 channel connection (nil) 06:09:52.12 channel status 3 06:09:52.12 channel status 2 06:09:52.12 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.12 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.12 channel connection (nil) 06:09:52.12 channel status 3 06:09:52.13 channel status 2 06:09:52.13 channel(out) 0xc86db0, readable 0, writable 8, cond 0 06:09:52.13 channel(in) 0xc89da0, readable 4, writable 0, cond 1 06:09:52.13 channel connection (nil) 06:09:52.13 channel status 3 06:09:52.13 channel status 2
— Reply to this email directly, view it on GitHub https://github.com/LBCrion/sfwbar/issues/32#issuecomment-1232117982, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASHPFFBA4E2GJNVQV7KFMGLV3ZTKZANCNFSM5ZZVHLPA . You are receiving this because you were mentioned.Message ID: @.***>
This is what I get running
sfwbar
on CLI , main as of today.The glib error is from previous versions back to beta6 as well. Just haven't had the time to report.
I'll post my configs too.
and
Screenshot