Well here is my first budgie-desktop applet:
Seen this before? Well yes – this is the Indicator SysMonitor app-indicator which has been updated to support budgie-desktop.
In-fact … it works much better under budgie because you don’t have to fiddle with applet ordering to stop applets jumping around with the SysMonitor label values grow/shrink in size. Just use Raven to order the applet correctly.
This is just a workout – to see what changes I need to do to get an existing python based app-indicator to natively work under budgie-desktop.
The changes were remarkably small.
Lets dive in.
First grab the source-code and install
sudo apt-get install python3-psutil curl git
mkdir -p ~/.local/share/budgie-desktop/modules
git clone https://github.com/fossfreedom/indicator-sysmonitor.git budgiesysmonitor
nohup budgie-panel --replace &
Then use Raven to add the “Panel Sys Monitor” applet
Ok – so what did I do to convert the existing app-indicator to work under budgie?
All local installed applets need to be installed into a subfolder of ~/.local/share/budgie-desktop/modules. An applet basically consists of two key files – “.plugin” which is the control file containing the description & Icon you see in Raven together with the name of the python module where budgie & Peas (the library that does all the clever stuff for the display of the applet) has the entry point to “run with”.
TIP: make the module name in the .plugin name the same as the folder name – its case-sensitive. So in this case the python module is “budgiesysmonitor.py” – so the module name is “budgiesysmonitor” and the folder name containing all the source is also “budgiesysmonitor”
TIP: make the .plugin filename the same as the Class entry point in budgiesysmonitor – so the filename is “BudgieSysMonitor.plugin” and the class entrypoint is “class BudgieSysMonitor(GObject.GObject, Budgie.Plugin):”
First comment out/delete the AppIndicator specifics – the gi.repository import AppIndicator statement etc.
Replace a line like “appindicator.Indicator.new(…)” with a Gtk container equivalent such as a button e.g. “button = Gtk.Button.new()”
Connect the signals that updates the Button Icon and/or label – for this applet sysmonitor just changes the label – there is no icon to display.
Add a test application wrapper :
win = Gtk.Window()
# setup an instance with config
win.add( button )
Run your new python app and make sure it works as you expect – click stuff, menu’s, display etc.
Then when you are happy, comment out the test app portion and just top and tail with the Applet specifics for Budgie i.e. the correct import:
from gi.repository import Budgie, GObject
The magic is this bit – two classes – the Peas entry point “BudgieSysMonitor” and the Panel Applet – our button is created here:
class BudgieSysMonitor(GObject.Object, Budgie.Plugin):
""" This is simply an entry point into the SysMonitor applet
Note you must always override Object, and implement Plugin.
# Good manners, make sure we have unique name in GObject type system
__gtype_name__ = "BudgieSysMonitor"
""" Initialisation is important.
def do_get_panel_widget(self, uuid):
""" This is where the real fun happens. Return a new Budgie.Applet
instance with the given UUID. The UUID is determined by the
BudgiePanelManager, and is used for lifetime tracking.
""" Budgie.Applet is in fact a Gtk.Bin """
button = None
def __init__(self, uuid):
# Add a button to our UI
self.button = Gtk.Button.new()
Test your new applet – you’ll need to shout at budgie-panel to make it recognise your new applet:
budgie-panel --replace &
See – easy!
P.S. before you complain – yes I should be using a Popover to display the menu when clicking the applet but that’s for another day.
Source – Ikey’s plugin examples – for C and Vala hackers there are similar example plugins in the linked github repo