xfce

Design Implemented

The design phase is now over and an implementation similar to what is described below is available from Xfce SVN.

What is still under development is the Panel User Interface for configuration of the new panel. Please join the discussion with your suggestions. -- JasperHuijsmans 08:48, 19 Oct 2005 (UTC)


Introduction

Read this first for the initial thoughts about changes in the panel design for Xfce 4.4:

This page is meant for discussion of a new design for the Xfce Panel and specifically for panel plugins. I'd be very interested in input from (potential) plugin writers.


Goals

The goals for the new panel design are (among others ;-):


Panel


Panel Plugins

    [Xfce Plugin]
    Name = Mail notification
    Comment = Show mailbox status. Supports multiple mailboxes and protocols.
    Icon = xfce-mail
    Exec = xfce-mail-plugin

UML

Well, probably not entirely correct UML, but some graphical representation of the classes and interfaces for the new panel:

http://xfce.loculus.nl/files/panel-design.png

API

Let's try and come up with an API that will be sufficient for any kind of plugin. Comments at the end of the code block, please.

 typedef _XfcePanelPlugin XfcePanelPlugin;
 typedef _XfcePanelPluginClass XfcePanelPluginClass;
 struct _XfcePanelPlugin
 {
     GtkPlug parent;
 }
 struct _XfcePanelPluginClass
 {
     GtkPlugClass parent_class;
     /* signals */
     void (*orientation_changed) (XfcePanelPlugin *, GtkOrientation);
     void (*icon_size_changed) (XfcePanelPlugin *, int);
     /* timing could be a problem with async communication */
     void (*save_yourself) (XfcePanelPlugin *);
 }
 /* Create plugin widget
  * Pass on commandline arguments that should give: 
  * - current panel settings
  * - plugin configuration
  * - GtkSocket to connect to
  */
 GtkWidget *xfce_panel_plugin_new (int argc, char **argv);
 /* get panel settings */
 GtkOrientation xfce_panel_plugin_get_orientation (XfcePanelPlugin *plugin);
 int xfce_panel_plugin_get_icon_size (XfcePanelPlugin *plugin);
 /* expand */
 gboolean xfce_panel_plugin_get_expand (XfcePanelPlugin *plugin);  
 void xfce_panel_plugin_set_expand (XfcePanelPlugin *plugin, gboolean expand);
 /* right-click menu */
 void xfce_panel_plugin_add_menu_item (XfcePanelPlugin *plugin,
                                       GtkMenuItem *item,
                                       GCallback activate_callback);
 /* configuration */
 /* TO BE DONE
  * - Suggestions are welcome. 
  * - A simple McsSetting-like API might be sufficient.
  */
 gboolean xfce_panel_plugin_has_key (XfcePanelPlugin *plugin,
                                     const char *key);
 void xfce_panel_plugin_remove_key (XfcePanelPlugin *plugin,
                                    const char *key);
 gboolean xfce_panel_plugin_get_key_value (XfcePanelPlugin *plugin,
                                           const char *key, 
                                           char **value);
 void xfce_panel_plugin_set_key_value (XfcePanelPlugin *plugin,
                                       const char *key,
                                       const char *value);
 /* convenience functions? _as_int, _as_float? */
 

Suggestions

For the configuration API: I'd use a simply key/value based API with only string values

 const gchar *xfce_panel_plugin_get_setting(XfcePanelPlugin *plugin, const gchar *name);
 void xfce_panel_plugin_set_setting(XfcePanelPlugin *plugin, const gchar *name, const gchar *value);

This fits all needs, as everything can easily be encoded into a string; maybe provide wrappers in the plugin-side library to convert the string to other values, similar to what XfceRc does. The get_setting() implementation in the Panel would check for translated values first (in the global config) and fallback to untranslated values.

And add:

 gboolean xfce_panel_plugin_has_setting(XfcePanelPlugin *plugin, const gchar *name);
 void xfce_panel_plugin_unlink_setting(XfcePanelPlugin *plugin, const gchar *name);

to allow plugins to cleanup obsolete settings after an upgrade.

For more advanced usage, there could even be

 gchar **xfce_panel_plugin_get_keys(XfcePanelPlugin *plugin);

in the core API to query all setting names for a given plugin.

  • It seems to me all the neccessary equipment for this is already in XfceRc, and that it would make sense to just have a single function to give the panel configuration:
 XfceRc *xfce_panel_plugin_open_settings(XfcePanelPlugin *plug);

--Ori


This is indeed what I have done now. Just as easy to use and less restrictive. -- Jasper 08:37, 27 Aug 2005 (CEST)


To speed up the plugin start with out-of-process plugins, the plugin-side library should query all settings for the plugin at once and cache them on the plugin-side to avoid the message ping-pong with several get_setting() calls on plugin startup. --Benny 14:42, 16 Mar 2005 (CET)

Yes, that is quite smart. Leave the parsing to the plugin writer. Most people will only need simple types (int or string), but more complex things would still be possible. -- Jasper 14:22, 16 Mar 2005 (CET)

The important point here is (IMHO): When you start with simple string key/value based core API, it's easy to extend it later if necessary; but if you start with complex key/value based core API (like gconf) it's hard or impossible to drop functions, that cause trouble or add too much unneeded complexity, later without causing too much breakage. --Benny 14:42, 16 Mar 2005 (CET)


About robustness: How about instead of heavy weight processes with a thick layer of communication, lightweight threads with a small shared memory portion for communication? Segv's and other fatal signals received for plugin threads could be taken care of since the main program memory is off limits for the plugins. This would cut down total system resources consumed. --Edscott


I'm concerned about in process plugins. Is it really needed? Doesn't Gnome do everything out of process? Admittedly, we've only had some problems with plugin stability thus far, but third part plugin writers are really picking up steam . . . --Erik

Yes, gnome does most/all plugins out of process with bonobo. This is now being reconsidered because of their current efforts to reduce memory footprint. -- Jasper 19:14, 16 Mar 2005 (CET)


I think most of the plugins would be of this type. First of all this is easier to program than using thread. But also we don't need to have always a process or thread running for each plugin.(don't forget, XFCE is a lightweight desktop:) ). Also, you want to pass to the plugin all the configuration stuff of the panel to the plugin what he loads... What about passing a pointer to the panel itself?

You can't do this for out-of-process plugins. Plus as far as I can see it will be only orientation and icon size that are useful for the plugins. -- Jasper 19:14, 16 Mar 2005 (CET)

This way plugins can:

If something like this would be useful I think it can better be implemented as a message to the panel (using the appropriate panel plugin api). -- Jasper 19:14, 16 Mar 2005 (CET)

OK, so if I understand well, you want to use separate processes (and not thread like I firstly tought) to improve robustness. I can agree this, but is it really needed? Can we try to use just thread instead? (EdScott wrote something about that above). I say that because I never had big problems with plugins, and I don't really feel the need to use separate process. (If some other people can say what they think about that...thx) --bountykiller <BR\>

Well basically, I'm a bit afraid of using threads with gtk. It's a mess and requires a lot of discipline to get right. We did try before, but there were all kinds of unexplained problems. Also I'd like to see the effect of separate processes first, before saying much about speed and memory issues. I have good hope it won't be too bad. -- Jasper 07:00, 18 Mar 2005 (CET)

I fully agree with Jasper. Making the panel threaded again would really hurt the stability. Gtk+ is not thread-safe and so we'd need all kinds of weird work-arounds/hacks to get things working. And the whole point in separating the plugins context from the panels context is to increase the stability/robustness of the panel, not to decrease it.--Benny 10:41, 18 Mar 2005 (CET)

OK :-) --bountykiller

The overhead of having separate processes is important, tho. IMHO, the best way to come around this problem would be to have the plugins available as loadable modules, and these modules can either be loaded into the context of the panel process or the context of a helper process, which then communicates with the panel. And give the user the possibility to decide (using a config file as this does not need a GUI) whether the plugin should be loaded into the panel or a helper process. The plugin should provide a hint to the panel (using a key in the .desktop file) if it prefers to run in the panel or a helper process; new plugins should set this hint to helper process until they've proven to work fine. This, of course, requires a well-thought and well-implemented API. --Benny 10:41, 18 Mar 2005 (CET)

Ooh, are you a mind reader now as well? ;-) I have been thinking about having a xfce4-panel-plugin-loader helper app, to load dynamic modules. Might be a bit of a double lookup (panel->fork helperapp->load module), but it also gives some flexibility.


I hadn't actually thought about making it optional though. Very interesting, thanks.

It's no biggie from the implementation. It just needs a good and stable plugin api. I think making it configurable is the only way for this to work out. There should be a way for a plugin to request to be run out-of-process, though, as some plugins may be design to run solely out-of-process (like a mailchecker, which can then use multiple threads or whatever); something like

X-XfcePanel-OutOfProcess=True

in the .desktop file should do the job. This is also necessary for plugins not written using the Gtk C API, but using a high-level language binding, like Xfc or PyGTK. For these kinds of plugins, there's also no need for a plugin helper binary, as it'll probably be impossible to ship these plugins as shared library that can be dlopen()'ed. Instead, the plugin provides the binary/script.


API suggestion by Alexander Iliev: provide a way for the plugin to set whether it is available, with explanation.

I think it should be sufficient to have a 'Unique = True' field in the desktop file. -- Jasper 07:56, 30 Mar 2005 (CEST)


Ideas and Requests

Let's use this place to collect loose ideas and requests about the new panel and plugin system.


The idea is that the iconbox and taskbar items will just be normal panel plugins. So, I think you will get what you want. -- Jasper