I’m currently messing around with GNOME 3 plugins, and there’s not a whole lot of information out there. Like, almost nothing. So, as I’m working on this stuff I will be posting up some information and some small plugins that demonstrate a certain feature. Whenever possible, I will also link to the relevant code or library function(or at least what I think the proper library/function is).
Alright, now let’s get onto the examples!
Create a new Extension
This is covered in most of the tutorials already, but we of course need an extension to edit! So, let’s create a new one with:
Now give it a name, description and UUID. You can see an example here. The new extension will be in
Once you have edited an extension, you will have to reload the gnome-shell in order for the changes to take effect. To do this, do ALT+F2, type ‘r’, and hit enter.
To view the output of the console, you will have to use systemd’s journalctl(for Debian 8, and probably RHEL 7). The command is:
journalctl /usr/bin/gnome-session -f -o cat
Also, you can enable-disable extensions using gnome-tweak-tool.
Example 1: DBus Connections
If you’re unfamiliar with DBus concepts, I recommend that you take a look at my DBus tutorial. The first thing that we are going to have to do is to define an XML interface(essentially, what the DBus Introspection method gives back).
So, using our old friend the DBus tutorial, we will create an interface that looks suspiciously similar to our first DBus example of simply echoing a string out to the console. Here’s the interface XML:
<interface name="com.rm5248.ReceiveInterface"> <method name="echoMessage"> <arg type="s" direction="in" name="message"/> </method> </interface>
Here’s the important part that actually connects to the bus(DBusIface refers to the XML that we defined above):
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject( DBusIface, this ); this._dbusImpl.export( Gio.DBus.session, '/' );
You can check to see that this method works using qdbus:
qdbus org.gnome.Shell / com.rm5248.ReceiveInterface.echoMessage hithere
You should now see the log printed out with your message.
This is all well and good, but what if we want to have our own DBus address? We don’t want everything to be under the org.gnome.Shell address. To do that, we simple need to acquire the well-known name on the bus that we want to use:
this._dbusId = Gio.DBus.session.own_name( 'com.rm5248', Gio.BusNameOwnerFlags.NONE, this._nameAcquired, this._nameLost );
A note on this though: your object will still be accessible from the well-known bus names of ‘com.rm5248’ and ‘org.gnome.Shell’. Essentially, ‘com.rm5248’ becomes an alias for ‘org.gnome.Shell’, so any path that you can access using ‘org.gnome.Shell’ you can also use ‘com.rm5248’. This perhaps not a bug, but it is contrary to how most bindings work.
The source that I used for testing can be found here. I’ve commented as much as I can, given my knowledge of how it works.
Example 2: Sending Messages
Now that we have our connection on the bus, and we can receive messages, how do we send messages out? Well, we need to do two things: Create a proxy, and then create an instance of that proxy. Once we have the proxy, we can call the methods asynchronously or synchronously. Here’s the important part of the code(note that DBusIface is the same XML that we defined earlier):
So, now we can call methods on other objects. You can get the source code for this example here. Also, a note on calling methods: there appears to be a bug when calling with the ‘sync’ method, in that it will take a long time to return. I will do some more investigation.
Coming up in our next tutorial: settings.