# Fvwm.py Manpage

## Synposis

This is a Python module that interfaces with the Fvwm module API. It allows you to write Fvwm extensions in Python. It is integrated with Python's Tkinter module, so you can easily write extensions that present a user interface.

### Classes

`FvwmModule`
  Top level class used to communicate with Fvwm.
`ConfigInfo`
  Class that encapsulates Fvwm module configuration lines.
`PacketReader`
  Class that encapsulates reading packets from Fvwm. This is actually represented by a family of derived classes, one per packet type, the base class of which is `Packet`

### Exceptions

`PipeReadError`
  Indicates an error while reading the file descriptor from Fvwm.
`SynchronizationError`
  Indicates that a partial, incomplete, or invalid packet was read from the Fvwm file descriptor.

### Module Functions

`error(msg, exit=None, flag='ERROR')`
  This function writes an error message to the module's standard error. Typically, this will get displayed on the system console. `msg` must be a string. Optional `exit` is an integer; if provided, this function will call `sys.exit()` with this value. Optional `flag` is a prefix to use when printing the message.
`debug(msg)`
  Print a debugging message on standard error. As above, `msg` must be a string.

### Module Variables

`Contexts`
  A dictionary of mappings between Context names as strings (as described in the Fvwm module documentation), and their numeric value. This dictionary also contains a reverse mapping.
`Types`
  A dictionary of mappings between Packet Types as strings and their numeric values. This dictionary also contains a reverse mapping.
`Flags`
  A dictionary of mappings between Window flags as described in `fvwm.h` and their numeric values. This dictionary also contains a reverse mapping.
`Gravity`
  A dictionary of mappings between Gravity flags as described in `X11/X.h` and their numeric values. This dictionary also contains a reverse mapping.

## Class Descriptions

### `FvwmModule`

The `FvwmModule` class is the main class for interaction with Fvwm. In typically usage, you will derive from this class and your applications will instantiate only one of these objects. The class provides an interface for sending commands to Fvwm, and a framework for dispatching callbacks on packets read from Fvwm. It also provides conveniences for setting the Fvwm event mask, and for getting module configuration lines and the window list.

There are two complimentary frameworks for creating callbacks. The first uses derived class methods, while the second uses registered functions with the latter always taking precedence.

Registration of callbacks is pretty simple. You simply call `FvwmModule.register()` giving the packet name (as a string), and a callback function object. The function should take two arguments, the first is the `FvwmModule` instance, and the second is the packet object. There is a complimentary `FvwmModule.unregister()` function.

For derived class methods, the names of the Fvwm packet types are used as keys for lookup. The mapping between packet names and method names is pretty straightforward (the listing of packet names is described in the Fvwm Module Interface Document). For a given packet name, the leading `M_` is removed, and the remaining symbol is stripped of underscores and converted to mixed-case format. For example, when the `M_ICON_LOCATION` packet was received, the method `IconLocation()` would be called. Derived class methods take two arguments as well: `self`, and the packet object.

If no registered callback and no derived method is found to handle a given packet, the method `FvwmModule.unhandled_packet()` is called, which also takes `self` and the packet object. You can, of course, override this in your derived class.

The `FvwmModule` class has some other useful methods and public instance variables:

`send(command, window=WINDOW_NONE, cont=1)`
  Sends a command string to Fvwm. Optional `window` specifies the window to apply the command to (note that this is the application's window ID; e.g. the `top_id` in the Tracker module's `Window` class). Optional `cont` is the continuation flag (see the Fvwm module documentation for details).
`set_mask(mask=None)`
  Sets the Fvwm event mask for the module. Optional `mask` can be a bit-wise OR of Context values. By default, the event mask is calculated automatically by searching for all implemented packet handler methods and registered callback handlers.
`start()`
  Start reading packets and dispatching on packet types. If the `Tkinter` module has been imported, and at least one widget has been created, this will start the Tk mainloop. Note that currently, recursive mainloops with Tk doesn't seem to be working properly.
`stop()`
  Stop reading packets.
`get_configinfo()`
  Returns a `ConfigInfo` instance which encapsulates the configuration lines from Fvwm.
`get_windowlist()`
  Sends the `Send_WindowList` command to Fvwm and reads all resulting packets, collating them into a Tracker instance, which is returned.
`program`
  Contains `argv[2]` of the module's initial command line.
`configfile`
  Contains `argv[3]` of the module's initial command line.
`appcontext`
  Contains `argv[4]` of the module's initial command line.
`wincontext`
  Contains `argv[5]` of the module's initial command line.
`args`
  Contains a list of the `argv[6:]` initial command line arguments.

### `Packet`

The `Packet` class is not directly accessible by your code. Instead, instances of it (actually of classes derived from it) are passed into the callback functions and methods. Packet classes are named in a manner similar to derived method names, except that the word `Packet` is appended to the name, e.g. `AddWindowPacket`. Usually the actual packet class name isn't important.

All packet objects have a common collection of public instance variables:

`pktlen`
  Total length of the packet, including the header, in unsigned longs.
`timestamp`
  The last timestamp received from the X server, expressed in milliseconds (note that this is not the Unix time!).
`msgtype`
  The packet type, as an integer.
`pkthandler`
  The packet callback name used to select a derived class method for dispatch.

Packets also have packet dependent public instance variables:

`NewPagePacket`
  `x`, `y`
    The X and Y coordinates of the upper left corner of the current viewport on the virtual desktop.
  `desk`
    The current desktop number.
  `max_x`, `max_y`
    The maximum allowed values for the coordinates at the upper left corner of the viewport.
`NewDeskPacket`
  `desk`
    The number of the currently active desktop.
`AddWindowPacket`, `ConfigureWindowPacket`
  `top_id`, `frame_id`
    ID of the application's top level window and the Fvwm frame window, respectively.
  `db_entry`
    Pointer to the Fvwm database entry.
  `x`, `y`, `width`, `height`
    Location and size of the window's frame.
  `desk`
    The desktop on which the window resides.
  `flags`
    The window's flag field.
  `title_height`
    The window's title height.
  `border_width`
    The window's border width.
  `base_width`
    The window's base width.
  `base_height`
    The window's base height.
  `resize_width_incr`, `resize_height_incr`
    The window's resize width and height increment, respectively.
  `min_width`, `min_height`, `max_width`, `max_height`
    The window's minimum and maximum widths and heights.
  `icon_label_id`, `icon_pixmap_id`
    The icon label's window ID (or zero) and the icon pixmap's window ID (or zero).
  `gravity`
    Window gravity.
  `text_color`, `border_color`
    Pixel value of the text and window border colors.
`LowerWindowPacket`, `RaiseWindowPacket`, `DestroyPacket`, `DeiconifyPacket`, `MapPacket`.
  `top_id`, `frame_id`
    The ID of the affected application's top level window, and the ID fo the Fvwm frame.
  `db_entry`
    The database entry for the window.
`FocusChangePacket`
  This packet contains a superset of instances variables of `LowerWindowPacket`. The additional variables are:
  `text_color`, `border_color`
    The pixel value of the text and window border colors.
`IconifyPacket`, `IconLocationPacket`
  These packets contain a superset of the instance variables of `LowerWindowPacket`. The additional variables are:
  `x`, `y`, `width`, `height`
    The location and size of the icon window.
`WindowNamePacket`, `IconNamePacket`, `ResClassPacket`, `ResNamePacket`, `IconFilePacket`.
  These packets contain a superset of the instance variables of `LowerWindowPacket`. The additional variable is:
  `name`
    The name or class of the window or icon.
`EndWindowlistPacket`, `EndConfigInfoPacket`
  No variables other than the common set.
`ErrorPacket`, `ConfigInfoPacket`, `DefaulticonPacket`
  `data`
    The string data.

### ConfigInfo

`FvwmModule.get_configinfo()` returns an instance of this class, which provides a convenient encapsulation of Fvwm module configuration lines. Instances of `ConfigInfo` have the following methods:

`get_infolines(re=None)`
  Returns all the configuration lines, as a list. With optional `re` parameter, only those lines `regex.match`'ing the regular expression are returned. Since the match starts at the beginning of the line, you do not need to include the `*' character at the beginning of the regular expression.

and the following public instance variables:

`iconpath`
  The value of `IconPath`.
`pixmappath`
  The value of `PixmapPath`.
`clicktime`
  The value of `ClickTime`.

## Caveats

There are several problems (IMO) with Fvwm's module API and functional interface. Notably there isn't a way to set both the desk and page with one command, and this introduces ugly update timing conditions in modules (such as the `FvwmPager`).

The nastiest problem that I've not been able to work around is that Fvwm likes to send pixel values for various color parameters. This isn't very useful to Tk based modules because Tk only understands X11 color names and there seems to be no way to convert from a pixel value (e.g. 0 - 255 on an 8 bit framebuffer) to the X11 color, without using an X11 Python module. Such a module does exist, but it's not distributed with Python and it's a shame to have to install and import that module just to decipher color parameters from Fvwm.

I wish instead that Fvwm would send an X11 color name. Understandably, sending the color's name as a string would introduce a variable width field in some packets. Instead the RGB style name could be used; e.g. `#RRGGBB` (Tk allows up to 16 bits per intensity, so `#RRRRGGGGBBBB` would have to be passed).

Last modified: Thu Dec 19 18:58:27 EST
© 1996 Barry A. Warsaw