Writing Python Applets for the budgie-desktop

Well here is my first budgie-desktop applet:

ubuntu xenial [Running] - Oracle VM VirtualBox : 1_027

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
cd ~/.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 :

# testing
win = Gtk.Window()

...
# setup an instance with config
win.add( button )
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

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:

import gi
gi.require_version('Budgie', '1.0')
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"

    def __init__(self):
        """ Initialisation is important.
        """
        GObject.Object.__init__(self)

    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.
        """
        return BudgieSysMonitorApplet(uuid)

class BudgieSysMonitorApplet(Budgie.Applet):
    """ Budgie.Applet is in fact a Gtk.Bin """

    button = None

    def __init__(self, uuid):
        Budgie.Applet.__init__(self)

        # Add a button to our UI
        self.button = Gtk.Button.new()
        self.button.set_relief(Gtk.ReliefStyle.NONE)
        self.add(self.button)
        self.show_all()

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

 

Advertisements

One thought on “Writing Python Applets for the budgie-desktop

  1. Pingback: budgie-remix roundup #1 | budgie-remix

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s