Mon, 08 May 2006

Porting plugins to the Xfce 4.4 panel

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.

Posted at: 19:20 | category: /wordpress | Comments (0)


Dealing with sessions in xfce4

So another post trying to help with common problems in xfce4. This time it is sessions.

By default xfce4 uses a session manager to decide which programs to start when logging in. There is also a mechanism for autostarting programs which is more appropriate for external programs. Here are some of the problems that often come up relating to sessions.

There are two ways of dealing with these problems. The first is pretty easy but requires logging out. The second is slightly more difficult, but can be done without logging out. The second technique is better suited to the last two problems listed above than the first two.

Method 1

First you need to enable saving sessions on logout. Go to the settings manager, and go to the “Sessions and Startup” page. Then check “Automatically save session on logout” and close it.

Now set up the session exactly how you want it to start. For instance get the panel running if it is not by going to a terminal and typing xfce4-panel. When you have it set up the way you want you should log out. When you log back in make sure everything is how you want it. If an app is not started that you want it to then you need to find a different way to do this, see the section on autostart at the bottom of this post. I suggest you then disable saving of sessions by unchecking the box in the settings manager the you checked a minute ago. This will make sure that your session stays that way for ever. If you ever want to make a change then you can go through this procedure again.

Method 2

This method involves editing directly the session managers config file for the session you are using. These files are located under ~/.cache/sessions/xfce4-session-hostname:X, where hostname is the hostname of your computer and X is the display you are using (usually 0). Open up this file in your favourite editor and have a look at it.

You will see groups of entries name Client0_*, Client1_*, etc. Each group of entries corresponds to one program that is launched. Look at each line that starts with ClientX_Program, and find the ones that you do not want. When you find one delet all of the lines that have the same Client* entry as the one that you do not want, e.g. if you don’t want (if you are on 4.4)

Client1_Program=xftaskbar4

then delet any line beginning with Client1.

You can repeat this process for all of the programs that you do not want.

When you have removed all of the unwanted entries then you need to get the file in to a state the the session manager can use again. To do this you need to renumber all of the ClientX lines so that the numbers are sequential, you need Client0_*, then Client1_*, etc, until you run out of entries, with no gaps in the numbers.

There is one final change to make, find the line that says

Count=3

or similar and change it to relect the actual number of programs left in the file. For instance if it said 3 before and you deleted 1 program then change it to 2. As a check it should be equal to the highest numbered Client line plus 1, if not then check your counting and numbering.

When you have finished save the file and all should be well next time you log in.

Autostart

To get external programs to start when you log in it is best to use the autostart features of xfce4, rather than the session manager.

If you are using 4.4 then simply open a terminal and type

xfce4-autostart-editor

This will open a graphical editor for your autostart items. You can check and uncheck the boxes to enable different programs, and if you click “Add” you can add new programs to run.

If you are on 4.2 then you can use the ~/Desktop/Autostart folder to create programs to autstart. If you simply want a program to run then create a symlink in this directory, e.g.

ln -s /usr/bin/firefox ~/Desktop/Autostart/firefox

If you want to do something more exciting, then create a shell script in this directory to do what you want, and mak it executable, it will then be run on autostart.

Posted at: 02:00 | category: /wordpress | Comments (0)


Sat, 06 May 2006

Getting the xfwm4 compositor to work in xfce4

I have put together a few pointers on the things that are required to get the compositor to work in xfce4. I have tried to include both 4.2.x and 4.4, but I might have missed something.

First you need an X server that supports composite, e.g. Xorg 7. You need to edit your xorg.conf file so that it contains.

Section “Extensions”
Option “Composite” “Enable”
EndSection

Then you need a version of xfwm4 that supports compositing. If you are compiling from source then you need to use the –enable-compositor switch (default in 4.4). You also need libxdamage-dev, libxfixes-dev, libxrender-dev and libxcomposite-dev (or whatever your distro calls them). When you are compiling you need to see

checking for xcomposite >= 1.0 xfixes xdamage xrender… yes
checking COMPOSITOR_CFLAGS… -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -I/usr/X11R6/include
checking COMPOSITOR_LIBS… -L/usr/X11R6/lib -lXcomposite -lXdamage -lXfixes -lXrender -lX11 -lXext

in the output. If not then I have probably missed a dependency.

If you are using a packaged version then you need to find out if it was compiled with this support, recent packages probably are.

Now you need to start xfwm4 with the compositor on, I think this is the default in all versions, but if not when you are running you can do

$ pkill xfwm4
$ xfwm4 –compositor=on

If it’s not on by default and you want it to be then there are two ways.

  1. If you are using the session manager then simply logging in, enabling saving of sessions, doing the above to start xfwm4 with the compositor then logging out and back in again, and disabling saving of sessions again should do the trick. I would find it easier to edit the files in ~/.cache/sessions, but each to their own
  2. If you are not using the session manager then edit ~/.xinitrc or /etc/xdg/xfce4/xinitrc

Once you have the compositor on then you will want something to do with it. There are some settings in window manager tweaks that may be of interest. Also try ALT+scroll wheel on the title bar of an app. You could also look into transset-df (or simply transset), or transd, which is kind of like devilspie for transparency. You could also look at my transparent Terminal patches. I also have patches the implement making inactive windows semi transparent.

Posted at: 10:14 | category: /wordpress | Comments (0)