NOTE: Some of this post is no longer relevant. Please use Universal Applet’s internal documentation.
At the moment, there’s very little documentation for developers describing the Universal Applets architecture. I’m hoping to roll out a stable release within the next week or two, and I should have the time to write up some docs after that.
In the meantime, this post should provide adequate installation instructions and a quick developer overview for those of you who have been asking. If you haven’t already done so, please read this article first.
Installing Universal Applets and Getting the Server to Run
1. Grab a copy of the branch off of bzr with the following command:
bzr co http://bazaar.launchpad.net/~aantny/screenlets/universal-applets
2. Install Universal Applets with the following:
sudo make install
3. Start the server with the following: chmod u+x src/share/examples/server.py src/share/examples/server.py
4. Start any screenlet or applet. There’s a non-screenlet-based test applet in src/share/examples/test-applet.py
The Universal Applets architecture is heavily built on XEmbed and DBUS. Any application can create an applet using a GtkPlug (or the equivalent widget in any X toolkit) and any application can display an applet using a GtkSocket. All communication between the applet (the process containing the GtkPlug) and the server (the process containing the GtkSocket) is done over DBUS.
There can be multiple servers running at any time. Each server can display applets in different places on the screen (e.g. in a sidebar or in a panel). In other words, the same applet can be displayed in different applications without requiring any modifications to the original applet. Accordingly, an applet server can easily display any applet without knowing or caring what language the applet was written in. Again, applets do not run in the same process as the applet server.
The Ten Second Component Overview
At this point, the only server is the aptly named server.py application that’s contained in my branch. server.py displays applets in toplevel windows. It runs a DBUS service and holds an array of GtkWindows and GtkSockets. (The toplevel windows are commonly referred to as “applet containers.”) Any application which would like to function as an applet server can do so by implementing similar DBUS code. Yes, it’s really that easy.
The AppletWrapper class implements all of the basic code necessary for an applet. It can be used to make any part of an app’s gui function as an applet. It handles the DBUS communication with the applet server and automagically takes care of all the nitty gritty XEmbed details. AppletWrapper is currently written in Python but I’m planning on reimplementing it in C.
In the layman’s terms: By using AppletWrapper any part of your app can gain toggleable applet status with about three extra lines of code. Nifty.
The Screenlets base class contains code for applets that need to implement custom drawing. It’s not absolutely necessary, but if you’re planning on writing a python applet you should probably subclass the Screenlets class. It supports theming and editable options (options that can be edited with a GUI) and will make your life simpler. Screenlets uses AppletWrapper for the magical DBUS and XEmbed ‘stuff’.
The session class is used by Screenlets to handle multiple instances. If you’re writing your own applet using AppletWrapper (or if you’re implementing your own equivalent to AppletWrapper) you can ignore it.
Other Important Notes:
There’s still some ugly and outdated legacy code from Screenlets in several places. In particular, I wouldn’t even try to understand the screenlets-manager.py file. It’s a coding nightmare and will be rewritten by the Universal Applet’s 0.1 release.
The server.py application (the name will change to something more original with the release) is the only currently the only applet server. There are plans to add support to Awn in the coming weeks.
There are still several features missing in Universal Applets that are present in the Screenlets. I’ve tried to focus on improving the stability and performance instead of adding new features. If someone wants to test the speed of my branch against screenlets’ trunk, I’d be interested in the results.
I’m reposting a shortened version of this email to the Gnome-love list. The bolded bit talks about the project’s current status.
I’m trying to fix the problem by creating a universal applets framework for GNOME that’s mostly based on Screenlets. The goal is to create a common applet format that can be easily loaded into any gtk (and even qt) application without forcing the applet developer to give up on specialized applet functionality.
The framework consists of two main parts- Screenlets and ScreenletContainers. Both are written in Python, but can easily be reimplemented in C or in any other language.
Screenlets contain a gtk.Layout. They can pack widgets into the gtk.Layout, draw on it, or do both. Screenlets support theming, editable options (options which save real time and can be edited with a gui), and DBUS services without any extra work on the developers part. They are completely scalable.
ScreenletContainers are responsible for loading and displaying Screenlets. The ScreenletContainer base class implements most of the functions necessary for loading and showing a Screenlet in a generic location. Any application can import the ScreenletContainer class and use it directly (or subclass it) to add on support for Screenlets.
There is a ToplevelContainer class which descends from ScreenletContainer and is responsible for embedding Screenlets in a toplevel window. ToplevelContainer adds on a few extra options for displaying Screenlets. (E.g. “keep above other windows”, “show on all desktops”, “show as a compiz fusion widget”, and so on and so forth.)
Right now, screenlets interact with their containers using hacked legacy code. Eventually, all communication will be done via DBUS and the screenlet will be embedded inside the container using GtkPlugs/Sockets. Dragging a screenlet from the desktop to Awn, Gnome-panel, or Kiba Dock will resize the screenlet and embed it in the dock/panel optionally only showing an icon sized preview.
Due to the way that things are going to be implemented, application developers will be able to wrap parts of their apps inside Screenlets. For example, if you have GIMP running, you’ll be able to pop the ruler screenlet out of GIMP and drag it on to your desktop. When you’re done using it on the desktop, you’ll be able to either dock it in the panel or drag it back into GIMP or even another app like Inkscape.
A few weeks ago I wrote up a post explaining the rationale behind the idea. You can find it here: http://theesylum.com/2008/02
The code is on launchpad here. One or two of the old screenlets may not work due to the major changes I’ve made lately. I’m going to push a revision in a few minutes fixing some of them.
Just to clarify, I’m (currently) the only developer working on this and (at this point) the code is independant of the Screenlets project. If anyone is interested in helping out then please email me.
It’s still a regression from the end users perspective. Don’t bother looking at it unless you’re a developer. There’s a slightly longer explanation here.
Quick side note: I really need to write a whole post about GHOP. For now, I’d just like to (publicly) give my thanks to everyone who participated and made it happen. You know who you are, and my email to the GHOP mailing list will have to suffice until I have the time to write a post here.