Date

With the 4.4 panel comes a new API. This change is to allow external plugins, which are run as processes separate from the panel, increasing its stability. This means that all plugins for the 4.2 panel have to be ported to work with the new API. The process is not too difficult, and below I have tried to outline some of the steps involved in doing it.

I recommed that you get hold of the xfce4-panel source, as this contains README.Plugins, which contains information about the API and how to use it, and includes lots of plugins that you can look at for examples of using the API. I also recommend that you get hold of the cpugraph plugin (version 0.3) as this contains an example of an external plugin, as well as useful examples of how to set up autotools for building an external plugin.

Autotools

The first step is to set up your plugin so that autotools will build all the relevant parts, and put them in the correct place. If your plugin doesn't use autotools then you need to do the same things as below in your Makefile.

First you need to check that the correct version of the panel is available to compile against. Edit configure.ac and find a line that looks something like

XDT_XFCE_PANEL_PLUGIN([XFCE4PANEL], [4.2.0])

and edit this so that it looks like

XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.3.20])

While you are editing configure.ac you should also bump your version numbers.

Then you need to alter the way that the plugin is built so that it is an executable rather than a shared library. Edit the Makefile.am in the source directory of the plugin so that it looks something like

plugindir = $(libexecdir)/xfce4/panel-plugins
plugin_PROGRAMS = xfce4-wavelan-plugin
xfce4_wavelan_plugin_LDFLAGS = @LIBXFCE4PANEL_LIBS@
xfce4_wavelan_plugin_SOURCES = /*list the source files of your plugin here*/
xfce4_wavelan_plugin_CFLAGS = @LIBXFCE4PANEL_CFLAGS@

The new panel looks for .desktop files in /usr/share/xfce4/panel-plugins to find out what plugins are available. You need to create one of these files, see README.Plugins for information on what it contains. A trick is employed to get the correct installation path in to the file, if you use intltool in your plugin see the cpugraph plugin to see how to do this, if not then create a file in your source directory names like pluginname.desktop.in, and put something like this in it.

[Xfce Panel]
Type=X-XFCE-PanelPlugin
Encoding=UTF-8
Name=Wavelan
Comment=View the status of a wireless network
Icon=xfce-mouse
X-XFCE-Exec=@PLUGIN_PATH@/xfce4-wavelan-plugin

Then the makefile needs to be changed to process this file to create the one to be installed. Edit Makefile.am again and add the following (different for intltool users)

# .desktop file
#
# Some automake trickery here. Because we cannot use $(libexecdir) in the
# automake stage, we'll use sed to get the full path into the .desktop file.
#
desktop_in_files = wavelan.desktop.in

desktopdir = $(datadir)/xfce4/panel-plugins
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)

EXTRA_DIST = $(desktop_in_files)

DISTCLEANFILES = $(desktop_DATA)

# get full path into .desktop file
%.desktop: %.desktop.in
sed -e "s^@PLUGIN_PATH@^$(libexecdir)/xfce4/panel-plugins^" \
$< > $@

Make sure the last two lines are indented by tabs, and that your editor has not expanded them to spaces.

Now you can run xdt-autogen to recreate the configure script and Makefile.in etc.

Changing the code

The code needs to be changed to use the new initialisation hook, and the new callbacks for events. See the README.Plugins for a description of the available callbacks.

The includes you plugin uses may need to be changed. If you use the util or gui packages then you only need to include

#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/libxfcegui4.h>

To import the panel stuff you will need to add

#include <libxfce4panel/xfce-panel-plugin.h>

You may also find the following two useful later on.

#include <libxfce4panel/xfce-panel-convenience.h>
#include <libxfce4panel/xfce-hvbox.h>

The first thing to add is the hook that will allow the panel to create an instance of your plugin.

XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL(wavelan_construct);

Then you need to provide the function named to that macro, which will create an instance of the plugin, and link it in to the panel to receive events that you care about. This will look something like

static void
wavelan_construct (XfcePanelPlugin *plugin)
{

/* The function that creates an instance of your plugin
and initialises all the values */
t_wavelan *wavelan = wavelan_new(plugin);

/* The callback to be informed when the panel changes
between horizontal and vertical. Use this if you care
which way up your plugin is */
g_signal_connect (plugin, "orientation-changed",
G_CALLBACK (wavelan_orientation_changed), wavelan);

/* called when the panel changes size. You should register this
and set size hints in the callback function */
g_signal_connect (plugin, "size-changed",
G_CALLBACK (wavelan_size_changed), wavelan);

/* Called to indicate the plugin should free all of it's data
as it is not needed anymore */
g_signal_connect (plugin, "free-data",
G_CALLBACK (wavelan_free_data), wavelan);

/* Called to indicate the panel should save its configuration
data */
g_signal_connect (plugin, "save",
G_CALLBACK (wavelan_save), wavelan);

/* IMPORTANT: this tells the panel to show a menu when the
user right clicks on your plugin. Without this the user
will not be able to remove your plugin easily*/
xfce_panel_plugin_menu_show_configure (plugin);

/* Called when the user chooses the properties option from
the right click menu. Here you should create a dialog for
the user to change configuration options */
g_signal_connect (plugin, "configure-plugin",
G_CALLBACK (wavelan_configure), wavelan);

}

Then you need to write all of the callback functions that you defined there. These can be simple wrappers around the functions you previously had (you may need to change arguments though). For instance

void
wavelan_save (XfcePanelPlugin *plugin, t_wavelan *wavelan)
{
wavelan_write_config(plugin, wavelan);
}

static void
wavelan_write_config(XfcePanelPlugin *plugin, t_wavelan *wavelan)
{
char *file;
XfceRc *rc;

if (!(file = xfce_panel_plugin_save_location (plugin, TRUE)))
{
return;
}

rc = xfce_rc_simple_open (file, FALSE);

g_free (file);

if (!rc)
return;

if (wavelan->interface)
{
xfce_rc_write_entry (rc, "Interface", wavelan->interface);
}
xfce_rc_write_bool_entry (rc, "Autohide", wavelan->autohide);

xfce_rc_close(rc);

}

The code above also shows the new way of dealing with rc files (which you should use). When all of this is done you can try compiling the plugin. You may find you have to change more code to get it to compile, it depends on the plugin.

When you can compile it try installing it and loading it in to the panel. If it is not present in the list of plugins check that the .desktop file is in the right place, and contains the right information (a panel restart might be required, I never quite worked it out). If the plugin does not load then try killing the panel and launching it from a terminal and watching for errors.

Good luck, and let me know if I have made any mistakes or need to add anything.