Shared Applet Server
If you stumble upon this you should note that this is not a finished document - merely a staging area for my thoughts.
This is a draft for my thoughts on a shared applet server for the Gnome desktop.
Breakdown
The abstract situation is this: We have an applet consumer and an applet provider. You can think of this as the panel and a standard Gnome applet, or a desktop widget layer and a widget inside it.
Design goals of the framework
- Support in process and out of process applets
Support applet on demand - ie. applets that are not constantly running but are only activated when they are needed. When they are no longer needed they can shut down
- Applets should be able to decouple their GUI from their implementation
- Applets should have the option to be able to run in different GUI configurations (think Plasma's panel+desktop modes)
- The regular "add applet"-workflow, where the user select the applets to run from a list of available applets
- That applications can opt to expose an applet while they are running without the user having to manually enable it. This should be done by interacting with a Desktop Shell.
Design
The AppletConsumer talks to the AppletBroker to get a list of all known applets. Possibly a list of applets meeting some specific requirement. These requirements could be
- Can show GUI in some special way
- Provides a given GInterface
- More?
The AppletProviders can then be implemented via DBus services, mapping some DBus interface, in-process libraries, or some other means of communication (web?).
The AppletProvider API could look something like this:
interface AppletProvider { /** * List all available UI types. These should be predefined namespaced strings. Allowed values could be * - gnome-applet-ui:Reduced (think "embedded in panel") * - gnome-applet-ui:Full (think "widget on desktop") * - gnome-applet-ui:Hidden (popup on activation like the Alt-F2 run dialog) * * Third parties can extend this list in another namespace. */ List<String> getUITypes (); /** * Get the names of all available GInterfaces provided by this applet. * * The idea is that applets can request interfaces from each other via the AppletBroker. * We can't use dbus interfaces because interface providers can run in-process (fx. in * the same panel process) and some situations might require the performance of direct method * calls. * * Interface names should be qualified with proper namespacing. */ List<String> getInterfaces (); /** * Get a widget ready for embedding in the parent UI (panel, desktop, application). * Note that not all applets need to provide a UI. */ GtkWidget getUI (String uiType);
Crackpot Idea On Exposed Interfaces: An application can expose a ApplicationActions interface that can give you a GtkActionGroup (or something) of actions you can trigger on the application. These could be added to the popup you get when right clicking the application in the panel's window list. This should remove the need application developers have for exposing tray icons when they really shouldn't. For example Rhythmbox' context menu could look like:
FIXME
The AppletBroker
As noted elsewhere the broker is used to manage the applets. I imagine it be an abstract class with a static factory for instantiating the correct subclass. This way we can have alternative broker implementations easily:
abstract class AppletBroker { AppletBroker getDefaultBroker(); List<String> listApplets (); List<String> queryApplets (<query>); AppletProvider getApplet (String name); /* Possibly signals to notify when applets are installed/removed */ }
Helper Classes
Needless to say there are a few utility methods that would be handy - like for example connecting a ui definition given a connector description.
What is so Cool About This?
Applets would be able to shut down their "backends" when they are unused. Think for example an applet implemented in Python. If the the interfaces where DBus interfaces it would be activated by DBus when neeeded. When nobody uses the interface anymore the entire Python VM can shut down. The GUI will stay in the panel when the backend shuts down, because the gui is running in the panel's process space.
Many of the pieces are already here. GtkBuilder provided much of the hard work. The actual implementation of this scheme is mostly marshalling code and XML parsing. Boring, but easy peasy.
- No daemon to manage the available applets is needed. The broker can easily just a class in a lib.
Can actually be used to embed generic plugins into any ol' application. This is where the abstract AppletBroker can come in handy.
What is Uncool About This
It is harder to add custom widgetry in the applet uis. It would need to load the custom widget code in a GModule or something. I actually don't know exactly how GtkBuilder goes about this.
Using GtkBuilder XML in the protocol makes it Gtk-bound - ie, Qt based platforms are unlikely to use it (but they have Plasma anyway)