# Creating themes for the &kdm; greeter

This section describes the creation of themes for the themed greeter. For examples including screenshots, see the installed standard themes and the themes from the theme website.

## Theme Overview

&kdm; themes can be created by creating an XML file that follows the specification in `$`KDEDIR`/share/apps/doc/kdm/greeter.dtd`. Theme files are stored in the directory `$`KDEDIR`/share/apps/kdm/themes/`theme_name``. The theme directory should contain a file called `KdmGreeterTheme.desktop` which has similar format to other `.desktop` files and looks like:

    [KdmGreeterTheme]
    Greeter=circles.xml
    Name=Circles
    Description=Theme with blue circles
    Author=Bond, James Bond
    Copyright=(c) 2002 Bond, James Bond
    Screenshot=screenshot.png

The `Name`, `Description`, `Author` and `Copyright` fields can be translated just like in other `.desktop` files. All the files that are mentioned should be in the theme directory itself. The `Screenshot` field points to a file which should be a 200x150 screenshot of the theme in action (it is OK not to have one, but it makes it nicer for the user). The `Greeter` entry points to an XML file that contains the description of the theme.

Once a theme has been fully tested, make a tarball that contains the directory as it would be installed to the `$`KDEDIR`/share/apps/kdm/themes` directory. This is the standard format for distributing &kdm; themes.

## Detailed Description of Theme XML format

### Toplevel Node

&kdm; themes are XML files with the <greeter> tag at their root. The toplevel node is an item node of type `rect` with an implicit fixed layout.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE greeter SYSTEM "greeter.dtd">
    <greeter>
    [...]
    </greeter>

Contained within the greeter tag can be the nodes described in the next sections of this document. Some of these nodes are containers (layout nodes, item nodes) which can contain other nodes again.

### Item Nodes

A &kdm; theme is created by specifying a hierarchy of item and layout nodes. Item nodes can have the following value for the `type` attribute:

button

- A button field. This field uses a Qt button.

  It is also possible to make any other item act like a button by setting its `button` attribute to `true`. However, it is better to use Qt buttons in &kdm; themes since these are accessible to users with disabilities.

entry

- An input widget like a line edit or combo box. Note that this is merely a placeholder for Qt widgets.

label

- A text label. Must contain either a `text` node or a `stock` node to specify the text.

list

- A face browser widget.

pixmap

- A raster image in a format that Qt supports, ⪚ PNG, JPEG, Tiff, etc.

rect

- A plain rectangle.

svg

- A vector image in SVG format.

For example:

    <item type="label">

An item that acts as a button:

     <item type="rect" id="disconnect_button" button="true">.

By default, the &kdm; login screen will disappear after authentication. This can result in flicker between the login screen and the session. The `background` attribute allows users to specify what elements of the theme are the background image. When used, this will cause &kdm; to remove all non-background items from the display and render the remaining `background` items to the root window. This can be used to create a smooth transition between the login screen and the session:

    <item type="rect" background="true">
      <normal file="background.svg"/>
      <pos x="0" y="0" width="100%" height="-75"/>
    </item>

To use a different background for login transition than the one used for login, the theme should specify two item nodes (which could contain pixmaps or svg images, for example). The item which corresponds to the greeter background should not have the `background` property while the item which corresponds to the transition background should have the `background` property. For instance :

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE greeter SYSTEM "greeter.dtd">
    <greeter>
      <item type="rect" background="true">
        <normal file="background_for_login.svg" element="background"/>
        <pos x="0" y="0" width="100%" height="100%"/>
      </item>
      <item type="rect">
        <normal file="background_for_greeter.svg"/>
        <pos x="0" y="0" width="100%" height="100%"/>
      </item>
      [...]
    </greeter>

In multi-screen setups, themes may also specify the look of other screens than the one the greeter is on - but typically only background items will appear there. To specify which screen(s) an item should appear on, the `screen` attribute can be used with the value being one of `greeter`, `other` or `all`, meaning the screen the greeter is on, all screens the greeter is not on and all screens, resp.

Each item can be given a name via the `id` attribute. Certain ids are recognized by &kdm; to give those items a special function:

`button` items and items with the `button="true"` attribute.

- Buttons typically trigger certain actions. Addionally, &kdm; will hide buttons whose actions are not available for some reason.

  Id Action
  - chooser_button Runs the XDMCP chooser.
  - disconnect_button Disconnect from remote session.
  - session_button Open the session type selection menu.
  - system_button Open a catch-all menu with various options and actions, depending on the configuration.

`label` items

- &kdm; will show/hide these labels and set their text depending on the state of the login dialog.

  Id Function
  - pam-error This displays the Login failed. message.

Widget embedding items

- &kdm; will embed particular Qt widgets into these items.

  Id Function
  - user-entry Entry field for username entry.
  - pw-entry Entry field for password entry.
  - domain-entry Some conversation plugins use this field to query a domain name. If this field is present, the related enclosing items should have show nodes with the type `plugin-domain-entry`.
  - talker This item should be of type `rect`. It represents the hot area of the greeter: it contains the `label` and `entry` items which concern the authentication process. If a given conversation plugin cannot match the existing items with its needs, it tries to embed a complex widget with an own layout into this item, thus completely overriding the theme's talker. Strictily speaking, &kdm; themes do not need to provide own talker designs at all, as all &kdm; authentication plugins are able make use of the `talker` item.
  - userlist This item must be of type `list`. If the user list feature is enabled, &kdm; will embed the user list widget here. Otherwise, this item is hidden.
  - xconsole This item should be of type `rect`. If the built-in `xconsole` feature is compiled in and enabled, &kdm; will embed the console log widget here. Otherwise, this item is hidden.

Other items

- &kdm; will show/hide these items depending on the configuration and the current state of the greeter. &kdm; does not impose type requirements on them, but they usually lend themselves to a particular type.

  Id Shown only when ...
  - timed-label ... timed login is in progress.
  - caps-lock-warning ... Caps Lock is active.
  - xauth-warning ... the &X-Server; requires no X authorization to connect.
  - userlist-rect ... the user list is enabled. By nesting the `userlist` item into this one, it is possible to create something like a frame around the list and have it shown only when the user list itself if shown.
  - xconsole-rect ... the built-in `xconsole` is enabled. Analogous to `userlist-rect`.

### Layout Container Nodes

Layout nodes appear inside item nodes and contain item nodes again. The type of the layout node determines the arrangement of its child nodes. An item node can contain one layout node of each type.

#### Box Nodes

Box nodes automatically arrange their children in a row. They are specified as follows:

    <box orientation="alignment" min-width="num" min-height="num"
        xpadding="num" ypadding="num" spacing="num"
        homogeneous="bool">

Where `num` means number of pixels and `bool` means either `true` or `false`. The `alignment` value can be either `horizontal` or `vertical`. If you leave any attribute off, it will default to zero for numbers, `false` for bools and `vertical` for the orientation.

The spacing is the distance between neighboring child items. The padding is the box' outer margin. If the box is homogeneous, the same amount of space is allocated to each child item.

#### Fixed Nodes

Fixed is a container that has its children laid out at precise coordinates. The size of this container is the smallest rectangle that contains all the children. Fixed has no extra attributes and so you just use:

    <fixed>

Then you put other items with proper position nodes inside it.

### Position Nodes

Each item can specify its position and size via the `pos` node. For example:

    <pos x="0" y="4" width="100%" height="100%"/>

If the size is not specified, it will be the item's natural size, called the size hint. Note that not all items have a useful size hint.

Both position and size can be given in percent and will be calculated relative to the size of the enclosing container in this case. For toplevel items it is the percentage of the whole screen. By appending circumflexes (`^`) to the size specification it is possible to modify it to be relative to the size of the enclosing item's enclosing item and so on.

If the item contains a box, `width` and `height` can be specified to be `box` to mean that they are supposed to be the width and height of the box, that is the items in the box plus the padding.

One of `width` and `height` can be specified to be `scale` to mean that it should be scaled according to the other dimension's scale relative to its size hint. Use this to preserve the aspect ratio of scaled images automatically.

If the `expand` attribute is specified and `true`, this item will be expanded in the enclosing box as much as possible (that is it will be given more space if available).

If `width` or `height` is a plain number, a negative value represents an offset from the enclosing container's size. Note that it is possible to specify a positive offset by writing two minus signs.

In either case it is possible to constrain the final size with the `min-width`, `min-height`, `max-width` and `max-height` attributes which can be specified in the same ways as `width` and `height`.

If `x` or `y` is a plain number, a negative value represents an offset from the right resp. bottom edge, unlike the default which is the left resp. top edge.

It is also possible to specify which point within the item the position refers to. This is called the anchor and can be either `c` for center or one of `n`, `ne`, `e`, `se`, `s`, `sw`, `w` and `nw` which stand for the different edges/corners corresponding the directions on a topographical map. The default is `nw`, which is the upper left corner. For example:

    <pos x="10%" y="50%" anchor="w" width="80%" height="95"/>

### Show Nodes

You can specify the `type` attribute to indicate that certain items should only be displayed if the type is set. Prefixing the type with an exclamation mark (`!`) reverses the condition. Valid values include the following:

Type Display if ...
- `chooser` switching to remote login is permitted.
- `halt` and `reboot` system shutdown is permitted.
- `system` no condition (always set in &kdm;).
- `plugin-``entry-name` the conversation plugin provides a corresponding input field.

For example:

    <show type="chooser"/>

Alternatively, you can specify a `min-screen-width` or `min-screen-height` value to indicate that certain items should be displayed only if the screen resolution is the at least the specified size. For example:

    <show min-screen-height="768"/>

### Normal/Active/Prelight Nodes

The look of most item types can be parametrized via the following tags:

`normal`

- Normal state.

`prelight`

- When the mouse is hovering over the item.

`active`

- When a mouse button is clicked on the item.

The exact set of available attributes depends on the item type:

`rect`

-     <normal color="#000000" alpha="0.0"/>

  Either of the attributes may be omitted, in which case the default is used (the example represents the defaults). `alpha` is a floating point number between zero (transparent) and one (opaque). `color` is a hashmark followed by a six-digit hex number; the format is `#``rrggbb`. Alternatively, `color` may be specified as an eight-digit hex number, in which case the first two digits are the alpha value.

`label`

-     <normal color="#ffffff" alpha="1.0" font="Sans 14"/>

  `alpha` and `color` are specified like in rect items.

  `font` follows the format `family-list` `style-options` `size`. Each part is optional.

  `family-list` is a comma-separated list of font families like helvetica, monospace, etc.

  `style-options` is a space-delimited list of keywords from the categories style, weight and stretch; from each category at most one. The style can be `normal`, `italic` or `oblique`. Weight can be `ultra-light`, `light`, `medium`, `semi-bold`, `bold`, `ultra-bold` or `heavy`. Allowable stretches comprise `ultra-condensed`, `extra-condensed`, `condensed`, `semi-condensed`, `normal`, `semi-expanded`, `expanded`, `extra-expanded` and `ultra-expanded`.

  `size` is either a floating point number representing the size in points (1/72 inch) or an integer followed by `px` representing the size in pixels. Point sizes are preferable, as they are independent from the display resolution.

  If either attribute is left out, the values from the style node are used. If this yields no window-text color specification, white is used. The default font is the one configured in &kdmrc;.

`pixmap`

`svg`

-     <normal file="picture.png" tint="#dddddd" alpha="1.0"/>

  `file` specifies the file containing the image. Relative pathnames are relative to the theme's directory.

  `wallpaper` can be used instead of `file` to have &kdm; look for images in the usual locations for &kde; wallpapers. Plasma wallpaper packages are supported.

  `element` specifies the element id of a SVG file. If empty, the whole SVG image will be rendered.

  For `pixmap` nodes, it is possible to provide multiple images, so the best-quality image for a given resolution can be used. Size-tagged file names have the format `basename``-``width` `x` `height``.``extension`. If the not size-tagged file exists and it is no Plasma wallpaper package, &kdm; will accept only a perfect match for a given size and otherwise fall back to the original file. Otherwise it will try to find an image whose dimensions come closest to the required size if no perfect match is found.

  `scalemode` specifies how to adjust the size of images which do not match the element's size. `free` (the default) means to simply scale the image to the right size, possibly distorting its aspect ratio. The other two modes maintain the image's aspect ratio: `fit` means to zoom the image to the maximal size which fits into the element's geometry. The image will be centered. The remaining area will not be painted by this element, so it should be placed on top of a solid-filled `rect`. `crop` means to zoom the image to the minimal size which completely fills the element's geometry. The image will be clipped symmetrically.

  `tint` and `alpha` form a color specification like in `rect` items. Each pixel of the image is multiplied with this color component-wise.

### Widget Style Nodes

This tag makes it possible to change the appearance of labels and Qt widgets embedded into the theme, e.g., line edits, buttons or the user list. The style settings are inherited by child items, but can be overridden individually. The defaults are taken from &kdmrc;.

The `font` attribute defines the font for all widgets. For widgets with an input function it can be overridden with the `edit-font` attribute. Fonts are specified the same way as in normal/active/prelight nodes.

Usually, the theming engine tries hard to remove any frames from Qt widgets, so they melt into the theme seamlessly. In cases where this is not desired, the `frame` attribute can be set to `true`.

The `guistyle` attribute can be used to override the Qt GUI style for embedded widgets. The default is given by `GUIStyle` in &kdmrc;

It is possible to specify almost the entire palette for the widgets as documented at Trolltech's site. Attribute names are composed from a scope, a color role and a suffix. Possible scopes are - in order of increasing precedence - `all-` for all color groups, no scope for the active and inactive color groups and `active-`, `inactive-` and `disabled-` for the respective color group. Supported color roles are `window`, `window-text`, `base`, `alternate-base`, `text`, `bright-text`, `highlight`, `highlighted-text`, `button` and `button-text`. The suffix can be `-color` or `-alpha` with the respective meaning as in normal/active/prelight nodes.

As an alternative to specifying the palette inline, the `colorscheme` attribute can be used to load a complete &kde; color scheme. The default is given by `ColorScheme` in &kdmrc;. Individual `color` specifications will override the colors from the scheme.

Example:

    <style edit-font="Comic 16" text-color="#dddddd" frame="true"/>

### Face Browser Color Nodes

Color nodes permit overriding the background color of the items in the face browser. `labelcolor` and `altlabelcolor` are essentially equivalent to `all-base-color` resp. `all-alternate-base-color` in style nodes. If only `labelcolor` is specified, alternating item backgrounds are disabled.

    <color labelcolor="#80ffffff" altlabelcolor="#80f0f0f0"/>

### Text Nodes

Text tags are used by labels. They can be used to display localized text as follows (if the `xml:lang` attribute is omitted, the POSIX locale is assumed):

    <text xml:lang="fr">Option</text>

Text nodes can contain the following special character sequences which will be translated as follows:

Sequence Expansion
- %% A literal % character
- %c Wall clock time and date
- %d Display name (`DISPLAY` environment variable)
- %h Hostname (`gethostname` output)
- %m Machine name (machine part of `uname` output)
- %n Node name (nodename part of `uname` output)
- %o Domain name (`getdomainname` output)
- %r Release name (release part of `uname` output)
- %s System name (sysname part of `uname` output)
- %t Remaining number of seconds until timed login is performed, plus the appropriate i18n plural form of second
- %u Username for timed login
- _ Causes the following character to be an accelerator

`%t` and `%u` are intended to be used only internally to display the `timed-label` message, which is automatically updated every second.

### Stock Nodes

Certain common localized labels can be specified via the stock tags. The `text` tag is ignored if the `stock` tag is used. You really should use the stock labels rather than just putting all the translations into the themes. This yields faster load times and likely better translations. The following values are valid:

Type Expansion
- caps-lock-warning Caps Lock is enabled
- chooser XDMCP Choose_r
- quit _Quit
- disconnect Disconn_ect
- halt Power o_ff
- language Lan_guage
- login _Login
- session Session _Type
- reboot Re_boot
- system _Menu
- timed-label User %u will login in %t
- domain-label _Domain:
- username-label _Username:
- password-label _Password:
- welcome-label Welcome to %h

For example:

    <stock type="welcome-label"/>

### Buddy Nodes

Items which do not directly cause an action can be assigned a buddy. The buddy is given input focus when the item is activated (clicked or a `label`'s accelerator pressed).

The buddy is referenced by id with the `idref` attribute. Obviously, it must be given an id. Example:

    <item type="label">
      <stock type="username-label"/>
      <buddy idref="user-entry"/>
      [...]
    </item>
    [...]
    <item type="entry" id="user-entry">
      [...]
    </item>