Here’s a scenario. You have a microcontroller that reads a lot of items – temperature, pressure, whatever – and you want to have a display for your Linux desktop that sits on the panel and shows you the status. When you click on it, you get the extended status and can even issue some commands. Most desktops support the idea of widgets, but developing them is a real pain, isn’t it? Even if you make a development for KDE, what will happen to the people who use the genome?
There seems to be a simple answer and it was apparently inspired by a tool from Mac World. That tool was called Beatbar (now Xbar). That program puts a widget in your menu bar that can display whatever you want. You can write any type of program of your choice – Shell Script, C, whatever. The printed output from the program controls what is displayed in the widget using a simple markup-like language.
That’s fine for Mac, but what about Linux? If you use the genome, there is a very similar project called Argos. It’s basically compatible with XBar, although there are some things that add to it that are specific. If you use KDE (as I do) you will want cargo, which is more or less a port of Argos and adds something of its own.
Good news, bad news
The good news is, theoretically, you could write a script that would run under three systems. The bad news is that everyone has their own differences and quirks. Obviously, also, if you use a compliant program that can cause problems on the Mac unless you re-compile.
To exacerbate that problem, Cargo’s documentation seems to be wrong. This is partly because the KDE repository version is outdated and even if you grab the latest release from GitHub, it is still outdated with the documentation. You really want to install from a clone of GitHub, not from the release package or from the KDE repository for Plasmoid. Also part of the problem, the documentation is trivial and you sometimes have things that work but not in every case. It is not clear if this is some design or interaction with the KDE desktop that is ever-changing.
Since I use KDE, I’m going to focus on Cargos, and I’ll talk about Argos as I go along. But you can expect to test something both ways.
Basic
When you install the widget, you need to point it to a script. In general, the script will run in phases. For cargoes, you can set that interval in two different ways which we will discuss later.
In the simplest case, you will have a line of script output text that will be displayed on the panel, a separator, and then one or more lines of text will be displayed when you click on the widget. Consider this:
#!/bin/bash echo Hello Hackaday echo --- echo Test echo 1 echo 2 echo 3 echo 4
If you place the Cargos Widget on a panel and set it to read your script, you will end up with only the text in Hello Hacked on your panel. When you click, you will see something like this:
Excitement
As such, it is not very exciting. However, each line of text may have a pipe character and may have some features to spruce things up and add functions. Replace a line with Hello Hackaday:
ICON=$( curl -s "https://hackaday.com/favicon.ico | base64 -w 0 ) echo "Hello Hackaday | image="$ICON" href=http://www.hackaday.com"
Now the panel will look a little snug and if you click on the small chain link icon, you will see your favorite website. Of course, the real interesting thing is when you can change items. If you set a refresh interval on the configuration screen, the script will run more often. You can name the script with a repeat interval. For example, its a script haddemo.10s.sh
Will run every 10 seconds but haddemo.2m.sh
Will run every two minutes.
You can add arefresh=true
Attribute to a text line so that when clicked the script can be run again. Suppose you want to ping Google on demand. You can set the timer to 0 and do this:
#!/bin/bash OUTPUT=$( ping -c 1 -q google.com | grep ^rtt | cut -d ' ' -f 4 | cut -d '/' -f 1 ) if [ -z "$OUTPUT" ] then echo "Error click to refresh | refresh=true color=orange" bash="'/usr/bin/systemsettings kcm_networkmanagement'" terminal=false fi # get an integer to compare (bash doesn't like floats) IOUT=$( echo $OUTPUT | sed s/\\.// ) COLOR=green if [ $IOUT -gt 90000 ] # 900000 is 90 ms then COLOR=red fi echo "Google.com: $OUTPUT ms | refresh=true color=$COLOR" bash="'/usr/bin/systemsettings kcm_networkmanagement'" terminal=false echo ---
Now you get a ping time from Google on your bar If it slows down or is unable to ping, it will color. A small button lets you open Network Management.
Anyway.
Colors doesn’t seem to be working in the dropdown menu, which may be the desktop manager forcing theme colors, so your mileage may change. There are also some differences compared to Argos. For example, Argos has an environment variable that tells you if the widget is open. It does not allow you to run unnecessary parts of your script for better performance.
There are other differences, too, but you should be good if you stick to the basics. Even where things are different, it’s still easier than writing two completely different widgets for different systems.
There seems to be some weird behavior. For example, the OnClick feature does not work on dropdown items either. Of course, it’s open source, so if you hate it too much, feel free to fix it!
Great example
Since I like to follow headlines on Hackday, I decided to take advantage of a feature of Cargoes. In previous examples, I only had one line before the dropdown divider (“-”). But if you have multiple lines, the widget will rotate through them slowly which you can set in the widget settings.
Use awk
It’s easy to read RSS feeds on Hacked and extract titles and links. A few pictures and you will end up with a beautiful RSS display. Parsing may not work for an arbitrary RSS feed because it is quite simple, but – theoretically – you will be able to adapt it to other feeds.
Here is the code:
</pre> #!/bin/bash curl "https://hackaday.com/feed/" 2>/dev/null | awk ' BEGIN { n=-1; } # skip first item /<title>/ { # read titles if (n==-1) next; gsub("[[:space:]]*</?title>[[:space:]]*",""); item[n]=$0; next; } /<link>/ { # read links if (n==-1) { n=0; next; } gsub("[[:space:]]*</?link>[[:space:]]*", ""); link[n++]=$0; next } END { # output widget text for (i=0;i<n;i++) { printf("%s | href=\"%s\" imageURL=https://hackaday.com/wp-content/themes/hackaday-2/img/logo.png\n",item[i],link[i]); } print "---" # output dropdown lines for (i=0;i<n;i++) { printf("%s | href=\"%s\"\n",item[i],link[i]); } } ' <pre>
This is not much code for a fully developed RSS reader. You can view the stories in the panel and either click on them or open the widget to see a list at once.
The next step
Since the data is text only, it is easy to extract small widgets using this system. For example, this is a pretty simple memory status widget:
#!/bin/bash cat /proc/meminfo echo --- echo "<b>Tools</b>" echo "--System status | bash=/usr/bin/ksysguard onclick=bash" echo "--Htop | bash=/usr/bin/htop" terminal=true cat /proc/meminfo
Obviously, having a script that reads data from an ESP32 or an Arduino would be trivial. Since the operating system is agnostic much of what you want to do with something like this, browsing some plugins for xbar can give you an idea.
If you want something more sophisticated for KDE, check out the scriptinitor. You can sort it out further, but it’s a bit more complicated to handle.
For some reason, I’m obsessed with hacking feeds. I turned it into a file system. It greets me when I log in Some of the plugins you will find include Bash and some Python Don’t forget that you can mix them together.