This document tries to popularly cover the following questions:

  * Introduction into themes & components
  * How fvwm-themes works
  * How to create your personal parts to use with fvwm-themes
  * How to create a new theme
  * CCDS (Component Configuration and Dependancy System)
  * Syntax of theme.cfg


Introduction into themes & components
-------------------------------------

Theme is just a set of its components. Themes are placed into directories.
Component is a meaningful part of the configuration, not something fixed.
There are standard components; it is easier if you stick to the standard
components, in this case you should not define component dependancies,
they are pre-defined. It is possible to create completely new components,
like 'joystick', 'wheel-mouse', 'menus-auto' and so on, but then there
should be defined their dependances, for example, 'wheel-mouse' component
requires something which 'bindings' provides, 'menus-auto' follows 'menus'.

Standard components are:

  background, bindings, buttons, colors, cursors, functions,
  functions-appbind, globalfeel, menus, menus-programs, menustyle,
  modules, settings, sound, startup, styles, windowlook.

The default theme contains all standard components.
A typical theme contains a subset of standard components, like:

  background, buttons, colors, menustyle, modules, windowlook.

Notation colors@cde - means 'colors' component in 'cde' theme.
Notation colors@    - means 'colors' component in any theme.
Notation @cde       - means 'cde' theme or all components in 'cde' theme.

It is possible to mix different components from different themes,
like background@multichoice, buttons@osx, colors@luthien, cursors@migo.

A component can come in several variants (reflected in menu) and can have
any number of options (also automatically reflected). Also a component can
be a complex one, i.e. include other components, like settings@default.

A simple component is defined in one file, more complex components
are defined in several files or even better in their own directories.


How fvwm-themes works
---------------------

This is kind of magic.
To be written.


How to create your personal parts to use with fvwm-themes
---------------------------------------------------------

For the user convenience, there are user-definable versions of all standard
component, where she can extend this component. For example, the user can
add more bindings in bindings-extra@personal component, more menus in
menus-extra@personal component and so on.

First, you should create ~/.fvwm/themes/personal directory, if it is not
created yet by some graphical utility. To add an extra component to the
personal theme, means to create a file in this directory with the name of
the needed component.

Examples:

$HOME/.fvwm/themes/personal/bindings-extra may contain:

  Key F13 	A	S	FuncFvwmWWW
  Key Help	A	A	Menu MenuFvwmHelp
  Key C	  	A	CM	FuncFvwmConsole

$HOME/.fvwm/themes/menus-extra may contain:

  DestroyMenu MenuFvwmPersonal
  AddToMenu   MenuFvwmPersonal "Personal" Title
  + "Mozilla Home%menu/www.xpm"        Exec exec mozilla http://mozilla.org/
  + "Remote Shells%menu/terminal.xpm%" Popup MenuMyRemoteShells
  + "Private%menu/home.xpm%"           Popup MenuPrivate

$HOME/.fvwm/themes/personal/startup may contain:

  AddToFunc InitFunction
  + I Exec sleep 5; panel
  + I Exec exec xterm -g 80x40+400+100 -fn 7x14 -fb 7x14b

Note, since the startup@default is empty, you may define your InitFunction
and StartFunction in either startup or startup-extra (we suggest startup@).

Don't forget to "Refresh the current theme" for your new components
to be reflected in the "Theme Management" menu, then choose them.


How to create a new theme
-------------------------

Create a directory for the new theme in ~/.fvwm/themes/ directory.
We highly suggest to add components of your theme one by one.
Adding an entire theme at once is hard and not really needed, adding
components one by one also ensures these component will be usable even
without rest of components in your theme.

The procedure for adding a new component.

  1) decide which specific component you want to implement
  2) find a theme, which has the same component, which you think is closer
     to the one you want to implement
  3) copy the existing component file(s) or component directory to your
     own theme directory
  4) if there is component.cfg, copy it too
  5) you may need to do something about theme.cfg, but usually you do not
  6) edit the copied files; don't add fvwm commands which are defined
     in other components if you want to get an independent component
  7) to see your work in action, choose "Refresh the current theme"
  8) you should now see your new component in your new theme
  9) you can load this component, but don't be upset if it does not work
     as you expected for the first time, repeat steps 6 and 9 :)
 10) repeat steps 6 and 7 as many times as needed;
 11) if you messed things up use Restart or unload (drop) your component

You can repeat this procedure for every component.

We suggest to put your images in mytheme/images subdirectories, like
it is done in other themes. There is internal support for these
subdirectories. But you can choose other places if you really need.

Creating a theme is an art. It is also a technical task. You should decide
about such things as division to files/directories, images, other resources.
Feel free to ask your questions on fvwm-themes-devel@ mailing list.

If you did it right, you get mytheme directory with several components.
Execute this command to pack a theme (or even several themes):

  % fvwm-themes-config --create-pack john_themes theme1 theme2

This creates a tarball containing ft-john_themes-0.6.x directory with
theme1 and theme2 subdirectories.

Now you can distribute this tarball file to other users.
To install a theme (or themes) in this pack one should execute:  

  fvwm-themes-config --install ft-john_themes-0.6.x.tar.gz

or to install it to a system wide place (usually as root):

  fvwm-themes-config --site --install ft-john_themes-0.6.x.tar.gz

Good luck in creating new themes.


CCDS (Component Configuration and Dependancy System)
----------------------------------------------------

Theme components behave differently, one can be a simple file, other can have
several options or go in several variants, or even both. Some options are
only fvwm configurations to be read (in this case it is important to specify
whether the option files are read before or after the main component file),
some options only set dynamical variables to be used by the main file
(usually this is done using FvwmM4 variables, but may be done using shell
variables; in this case an option has no associated file to be read).

The order of reading components is very important. The order between
components can be specified by providing their dependancies, say colors@
provides colors-menus item, and menus@ requires colors-menus item, so
colors@ will be read before menus@.

Both two things mentioned above (component configuration and dependancy)
is covered by CCDS and defined in theme.cfg file in every theme.
If theme.cfg is absent in the theme, the default one is used, which
should work well for themes using only standard components.

theme.cfg may include other .cfg files, usually there is one .cfg file for
every non-simple component. If you your component has several options or
variants, it is suggested to add a corresponding component.cfg, where all
options are defined, instead of adding theme.cfg.


Syntax of theme.cfg
-------------------

The lines started with '#' sign are comments.
The like with only spaces/tabs are ignored.

Directives started with '!' sign, currently there are following directives:

  !include file.cfg  # includes another file.cfg in this directory
  !include-quiet file.cfg  # the same, but ignore if file.cfg is not found

There are several sections of 2 types:

  [theme] - one such section should be defined
  [component] - every such section corresponds to a theme component

A line in theme.cfg usually has a format key=value, where
  value is a string, which may mean id, label, number or anything else
  key may be string as well, but it is usually more complex

A section is actually a hash of key=value lines, but since a flat hash
is not a good data structure this hash usually contains array of other
hashes.

If you don't understand these several paragraphs, skip them.
We are using here a terminology of perl, where array corresponds to a list
of something (strings or hashes), and hash is dictionary or in other words
a list of pairs (key, value). All perl values requiring consisting from
scalars, ARRAYs, HASHs can be defined in theme.cfg syntax by using symbols
dot, plus, colon. Here how we can define array named key0
ARRAY [ HASH { key1 => value1, key2 => value2 }, HASH { key1 => value1 } ]

  key0+key1=value1
  key0.key2=value2
  key0+key1=value1

To define array values, like [ Peter, John ] and [ red ], the following
syntax is used (note plus before equal sign):

  team+name+=Peter
  team.name+=John
  team.color+=red

[theme] section includes the following keys:

  file - the theme directory if different; never really needs to be defined

  name - the name-to-show of the theme, if not defined - use 'file' key

  version - the version of theme.cfg format, currently not used

  component - array of logical components, note that list of the actual
    components, which is a subset of this array, is evaluated dynamically
    by checking whether the file or directory of the given component exist

  group - array of hashs with keys (name, component), used to define
    component groups, like [ all ], [ basic look ].

[component]

  file - the component id, it is the same as component file

  name - the name-to-show of the component, if not defined - use 'file' key

  provides - array of item that the component provides

  requires - array of item that the component requires

  follows - array of component that the component follows

  precedes - array of component that the component precedes

  start-stop - array of hooks that are called when the component is entered
    (start hook) and when the component is left (stop hook)

  local-imagepath - array of subdirectories of theme/images directory,
    which are used by the component, they will be added to ImagePath

  external-imagepath - array of directories the component uses and expects
    to be added to ImagePath

  read-command - fvwm command to use instead of Read main-component-file

  priority - flag 0 (default) or 1, defines a priority of the component

  contains - array of subcomponents if the component is a complex component

  variant - array of hashs with keys (file, name), variants of the component

  default - default variant index, starting from 1

  current - current variant index, starting from 1

  option-read-afterward - flag, 1 means read options after the main file

  inline - flag, 0 (default) means show every option in a separate place,
    1 means show all options in-line (in the same menu)

  option - array of hashs with keys (value, default, current,
    read-command, read-afterward), defines component options;
    value itself is array of hashs with keys (file, name)