Customising Window Behaviour in KDE

Richard Moore

1.00.00


1. Introduction

The default environment provided by KDE is fine for the majority of situations, but there are times when you want to exercise more control over things. KDE comes with a range of tools which allow you to override the default policies of the window manager, the taskbar and the other components that form the basis of the desktop environment. This article will give an introduction to the customisation tools provided by KDE and provide a few extra utilities to give you even more control over your KDE desktop.

2. The Structure of a KDE Desktop

KDE is built using the X Window System (X11) which, unlike monolithic desktop designs (such as Microsoft Windows or MacOS), divides the basic operation of the desktop between a number of components. I won't descibe the details of this division and its effects here, instead I'll just provide enough information to allow you to take advantage of it by treating it as a 'black box'. There are only two components we need to consider in this article: the window manager and the taskbar.

The window manager is a critical component of any X11 based environment, it provides the frame, title bar and other decorations of each window, and is also responsible for handling desktop-wide tasks such as resize policies, keyboard focus and virtual desktops. KDE provides as standard a powerful window manager kwin, which provides all the standard features of an X window manager (eg. virtual desktops and variable focus policies) and some less standard feaures such as themable window decorations and plugin support. Applications interact with the window manager using 'hints' which specify their desired title, window size, position etc., as the name suggests the window manager may ignore these requests. The X11 standard specifies a number of hints in order to allow applications developed using different toolkits to interoperate and these are almost universally supported.

The standard window manager hints were sufficient for early X desktops such as twm, but proved insufficient for more advanced window managers such as fvwm and mwm. These second generation window managers defined extra hints to provide developers with more control over their application's visual appearance. The arrival of a third generation of window managers such as Enlightenment and kwin with an even wider range of features, raised the danger of making the range of hints so complex as to be unusable.

To prevent this fragmentation, the developers of this new wave of window managers worked together to define a common standard set of extra hints which will be supported across the board. The resulting standard is known as the NET window manager specification and defines a set of hints that extend the basic ICCM specification with addititional facilities for i18n (such as utf8 window titles) and common framework for common tools like virtual desktops and taskbars. The result of this work is that any application making use of the NET properties should operate perfectly in any enironment that supports the NET hints. A practical example of the benefits of this can be seen in this screenshot which shows a KDE taskbar (the Kasbar kicker extension) running under fvwm with a NET WM extension.

3. kstart, A Practical Application

Now that we've covered the concepts underlying the NET specification, we can move on to look at how we can make use of it. The simplest way to access the NET facilities is to use a little known utility kstart which is included in KDE 2.1 and above. KStart lets you control the way an application interacts with the window manager by overriding its WM hints.The command is usually used to define special behaviour for commonly used applications, but it can also be useful for integrating non-KDE applications into your desktop.

Using kstart is easy: you simply put kstart and some options before a command. To begin, lets look at how we might use kstart to customize the behaviour of a kcalc window. The command we'll use is as follows:

 kstart --ontop --alldesktops kcalc

With luck, the affect this command has should be fairly obvious - the kcalc window will stay on top of all the others and be visible on every virtual desktop. A feature that is less obvious is that this command will work with any NET compliant environment, not just KDE.

We can pass arguments to programs we invoke with kstart as normal, for example:

kstart --skiptaskbar --desktop 1 xmessage 'Hello World'

This command displays 'Hello World' with xmessage and ensures that the window will be shown on the first virtual desktop and will be omitted from the taskbar. The fact that this program is written using the Xt toolkit rather than being a native KDE application does not cause any problem for kstart, hopefully this illustrates how kstart can be used to integrate foreign applications into your KDE desktop.

4. The System Tray

Now that we know how to customise the decoration of a window lets take a look at another aspect of the desktop, the system tray. The system tray is an area in which an application can display a small window, it is used to display status information or provide quick access to commands. A window that has an item in the system tray usually disappears from the task manager when minimised with the tray icon providing a replacement. Normally tray icons are specifically developed as part of an application, but as with window decorations KDE provides a tool for changing this, ksystraycmd.

To begin with, we'll take a standard application kcalc and turn it into a system tray application. This is acheived with one simple command:

 ksystraycmd --title 'kcalc' kcalc 

The icon shown in the tray is the one specified in the window hints and will be updated if the icon changes, the window title is shown as a tooltip if you hold the mouse over the icon. ksystraycmd follows the behaviour specified in the KDE Style Guide so the target window can be shown and hidden by clicking the tray icon, and a standard context menu is available.

5. More Complex Uses Of ksystraycmd

To illustrate the other features of ksystraycmd, we'll use a more example: a konsole window tracking the .xsession-errors file (this is the log file that records what's happening on your desktop). To begin with, we'll simply look at how we can view this:

 konsole --icon log --caption 'X Log' \
         --nomenubar --notabbar --noframe \
         -e tail -f ~/.xsession-errors 

The --caption and --icon arguments are provided as standard by KDE applications, you can get a full list of these global options by running an application with the --help-kde and --help-qt parameters. Here we give our konsole window with the title 'X Log' and the icon log. You can use these options with any KDE application and as I mentioned above ksystraycmd takes account of these when creating the tray icon. The '-e' argument is specific to konsole and tells it to run the less command. Despite its complexity, we can easily move this window into the tray with ksystraycmd:

 ksystraycmd --hidden --title 'X Log' \
             konsole --icon log --caption 'XLog' \
                     --nomenubar --notabbar --noframe \
                     -e tail -f ~/.xsession-errors

In addition to being the most complex command we've used, this example demonstrates the --hidden option which starts the command with only the system tray icon visible. This example achieves our aim of providing quick access to the log file, but we can do things a little more efficiently if we only run the konsole process when it is visible. The command we use is:

 ksystraycmd --startonshow \
             --icon log --tooltip 'X Log' \
             konsole --icon log --caption 'X Log' \
                     --nomenubar --notabbar --noframe \
                     -e tail -f ~/.xsession-errors

The addition of the --startonshow parameter tells ksystraycmd to start with only the tray icon visible (like the --hidden parameter), and to wait until the user activates the tray icon before running the target command. We've also used the --quitonhide parameter which tells ksystraycmd to terminate the target app whenever its window is hidden. Using both these parameters ensures that our konsole tray icon doesn't waste resources when we aren't using it. Creating and destroying the target window as we do here prevents the standard icon and title handling of ksystraycmd from working, so we now need to specify the initial icon and tooltip explicitly too.

6. Improving Reliability

In all of our previous examples we've relied on kstart and ksystraycmd to figure out which window we want to affect, and unless say otherwise, they assume that the first window to appear is the one we want. This policy is usually ok because we are starting the application at the same time, but it can fail badly when lots of windows are appearing (such as when you log on). To make our commands more robust we can use the window parameter, this specifies the title of the target window. The following example uses the window parameter to ensure that a particular konsole window is affected:

kstart --iconify --window 'kstart_me' konsole --caption 'kstart_me' -e tail -f ~/.xsession-errors

Here we've used the tried and tested technique of specifying a title for both kstart and the target application, this is generally the best way to use kstart and ksystraycmd. The window argument is supported by both kstart and ksystraycmd and can be regular expression (e.g. 'window[0-9]') as well as a particular title (regular expressions are a powerful pattern matching tool you'll find used throughout KDE.)

7. Conclusion

Now that you know how to tweak the way your applications interact with KDE, you should be able to make things work exactly as you wish. When you start writing more complex tweaks don't forget that you can use all of the techniques I've described on the same window which gives you a lot of scope for experimenting. I've only covered a few of the most common options here, for a full list of the facilities of kstart and ksystray command see their --help option.