   This is Edition 0.6, last updated 12 December 1999, of `The sawfish
Programming Manual', for sawfish, Version 0.19.

   Copyright 1999 John Harper.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Colors
******

   Sawfish provides a primitive type allowing colors to be represented.
Each color object allows a single color value to be named and passed
between Lisp functions.

 - Function: colorp arg
     Returns `t' when ARG is a member of the color type.

 - Function: get-color name
     Returns the color object representing the color specified by the
     string NAME. This is according to the standard X11 color
     specifiers, either a named color from the `rgb.txt' database, or a
     string defining the red, green and blue components of the color,
     either eight or sixteen bits in hexadecimal, i.e. `#RRGGBB' or
     `#RRRRGGGGBBBB'.

     Signals an error if no known color has the name NAME.

 - Function: get-color-rgb red green blue
     Return the color object representing the color with RGB components
     as specified (each component ranging from 0 to 65535).

   Given a color object, it's possible to find both the actual rgb
values defining the color and one of the names that X11 uses to refer
to the color.

 - Function: color-rgb color
     Return a list of integers `(RED GREEN BLUE)' the actual color
     values of the color represented by object COLOR. The individual
     values range from 0 to 65535.

 - Function: color-name color
     Return a string defining one of the X11 names used to specify the
     color represented by the color object COLOR. Note that this may
     well be different to the name used when the color was originally
     allocated.

   Where a color object is used to define the foreground color of a
piece of text, the `default-foreground' color provides the default value
used if no actual color is specified.

 - Variable: default-foreground
     The color used for text where no other color is defined.

Fonts
*****

   As with the color type, the font type allows X11 fonts to be
manipulated by Lisp code.

 - Function: fontp arg
     Returns `t' if ARG is a font object.

 - Function: get-font name
     Return a font object representing the X11 font specified by the
     string

     Signals an error if no font named NAME is available.

   Several functions allow the attributes associated with a font object
to be found.

 - Function: font-name font
     Returns the name of the X11 font represented by object FONT (a
     string).

 - Function: font-height font
     Returns the bounding height of glyphs in the font represented by
     object FONT.

 - Function: text-width string &optional font
     Returns the number of horizontal pixels that would be required to
     display the text STRING using font object FONT (or the value of
     the `default-font' variable if FONT is undefined).

   As with colors, a default font may be specified, to be used where no
other font is specified.

 - Variable: default-font
     Font object used when no other font has been specified.

   Fonts can have Lisp properties associated with them (similar to the
property lists associated with symbols). Currently these aren't
actually used by the window manager.

 - Function: font-put font property value
     Associate the lisp object VALUE with the property named by the
     symbol PROPERTY of the font object FONT.

 - Function: font-get font property
     Return the value of the property named by the symbol PROPERTY of
     the font FONT, or `nil' if no such property exists.

Images
******

   The image type allows arbitrary 24-bit images to be manipulated by
the window manager. Images may be both loaded from files, and rendered
dynamically.

 - Function: imagep arg
     Returns `t' when ARG is a member of the image type.

 - Function: make-image FILE-NAME
     Creates and returns an image object containing the image defined
     by the contents of the file named FILE-NAME (a string). The
     `image-load-path' directory provides the search path used while
     trying to find a directory containing the file named FILE-NAME.

     All common image formats will likely be able to be loaded. But PNG,
     JPEG and XPM should always be supported.

     Signals an error if file called FILE-NAME may be found, or if an
     image may not be constructed from the file.

 - Variable: image-load-path
     A list of directory names. This defines the search path used when
     loading images.

 - Function: make-sized-image width height &optional color
     Create and return a new image, of size WIDTH,  HEIGHT. If COLOR is
     defined it specifies the color of all pixels in the image. If
     undefined, all pixels will be black.

 - Function: copy-image image
     Returns a newly allocated image object, an exact copy of the image
     object IMAGE.

 - Function: image-dimensions image
     Returns a cons-cell `(WIDTH . HEIGHT)' defining the dimensions of
     the image represented by IMAGE.

 - Function: flip-image-horizontally image
     Flip the contents of IMAGE about the vertical axis.

 - Function: flip-image-vertically image
     Flip the contents of IMAGE about the horizontal axis.

 - Function: flip-image-diagonally image
     Flip the contents of IMAGE about an axis running from the top-left
     corner to the bottom-right corner of the image.

   As with many of the other types, arbitrary state may be associated
with image objects.

 - Function: image-put image property value
     Set the property named PROPERTY (a symbol) of IMAGE to VALUE.

 - Function: image-get image property
     Return the property named PROPERTY of IMAGE, or `nil' if no such
     property exists.

   The only predefined property is the symbol `tiled', used when an
image is displayed in a window decoration. When set to a non-nil value
the image is not scaled to the size of the decoration (the default),
but is tiled across the decoration.

   When images are scaled across border decorations the pixels that are
actually scaled are defined by the "border" of the image. The border
defines the outer rectangle of pixels that are left as-is, and the
inner rectangle which is scaled.

 - Function: image-border image
     Returns a list of integers `(LEFT RIGHT TOP BOTTOM)', the border
     of the image object IMAGE.

     The number associated with each edge of the image defines the
     number of pixels adjacent to that edge that _will not_ be scaled.

 - Function: set-image-border image left right top bottom
     Sets the border of IMAGE.

   The shape of the image may also be specified, this defines which
pixels are treated as being transparent. Each image may define a single
color as marking transparent pixels.

 - Function: image-shape-color image
     Return the color marking transparent pixels in IMAGE, or `nil' if
     no such color has been specified.

 - Function: set-image-shape-color image color
     Specify that COLOR marks transparent pixels in IMAGE.

   It's also possible to define "color modifiers" for each image.
These define the transformation applied to the value of each pixel when
it is displayed. Four different modifiers exist for each image, one for
each color component, and one for the image as a whole.

 - Function: image-modifier image type
     Return the modifier defined by the symbol TYPE of IMAGE, a list of
     integers `(GAMMA BRIGHTNESS CONTRAST)'.  Each integer has a value
     between zero and 255 representing the weight applied to the
     associated attribute when rendering the image.

     The four types are `red', `green', `blue' and `nil' (all colors).

 - Function: set-image-modifier image type gamma brightness contrast
     Set the image modifier of IMAGE defined by TYPE.

   There are also several other functions manipulating images:

 - Function: bevel-image image border upwards &optional bevel-percent
     Transform the edgemost pixels of IMAGE to give it a "bevelled"
     effect. BORDER is an integer defining the width of the bevel. If
     UPWARDS is non-nil the bevel is raised, otherwise it is lowered.

     If BEVEL-PERCENT is defined it specifies the height or depth of
     the drawn bevel. When undefined, the value of the parameter is
     taken from the `default-bevel-percent' variable.

 - Variable: default-bevel-percent
     Default height of drawn bevels, as a percentage.

 - Function: clear-image image &optional color
     Set all pixels in IMAGE to COLOR (or black if COLOR is undefined).

 - Function: tile-image dest-image source-image
     Tiles SOURCE-IMAGE into DEST-IMAGE, starting from the upper-left
     corner, working outwards.

Cursors
*******

   Cursors define the shape and hot-spot of the mouse pointer's image. A
lisp type is provided for manipulating these objects.

 - Function: cursorp arg
     Returns `t' if ARG is a member of the cursor type.

 - Function: get-cursor data
     Returns the cursor object representing the cursor defined by DATA.
     If DATA is a symbol, it's replaced by its `cursor-shape' property.

     Possible DATA values are an integer representing a glyph in the
     standard X11 cursor font, or a four-element vector.

     If a vector the format is `[IMAGE MASK FG BG]' where IMAGE and
     MASK are the filenames of standard X11 bitmaps, and FG and BG are
     colors (or names of colors). All bitmap files are searched for
     using the `image-load-path' variable.

 - Function: recolor-cursor cursor fg bg
     Change the colors of the cursor object CURSOR to FG and BG (either
     color objects or the names of colors).

 - Function: default-cursor cursor
     Set the cursor object displayed in the root window, and in parts of
     window frames that have no other cursor specified, to CURSOR.

   So that the integer indices of glyphs in the X11 cursor font do not
have to be remembered, the `cursor-shape' properties of the following
symbols are automatically set:

`X_cursor', `arrow', `based_arrow_down', `based_arrow_up', `boat',
`bogosity', `bottom_left_corner', `bottom_right_corner', `bottom_side',
`bottom_tee', `box_spiral', `center_ptr', `circle', `clock',
`coffee_mug', `cross', `cross_reverse', `crosshair', `diamond_cross',
`dot', `dotbox', `double_arrow', `draft_large', `draft_small',
`draped_box', `exchange', `fleur', `gobbler', `gumby', `hand1',
`hand2', `heart', `icon', `iron_cross', `left_ptr', `left_side',
`left_tee', `leftbutton', `ll_angle', `lr_angle', `man',
`middlebutton', `mouse', `pencil', `pirate', `plus', `question_arrow',
`right_ptr', `right_side', `right_tee', `rightbutton', `rtl_logo',
`sailboat', `sb_down_arrow', `sb_h_double_arrow', `sb_left_arrow',
`sb_right_arrow', `sb_up_arrow', `sb_v_double_arrow', `shuttle',
`sizing', `spider', `spraycan', `star', `target', `tcross',
`top_left_arrow', `top_left_corner', `top_right_corner', `top_side',
`top_tee', `trek', `ul_angle', `umbrella', `ur_angle', `watch', `xterm'.

   The glyphs associated with these names are shown in Appendix I, of
Volume Two, `Xlib Reference Manual'.

Windows
*******

   One of the most important data types in sawfish is the window type.
All managed client windows have a single window object associated with
them.

 - Function: windowp arg
     Returns `t' if ARG is a member of the window type, and has a
     client window associated with it.

 - Function: managed-windows
     Returns a list containing all managed window objects, in the order
     that they were adopted by the window manager (first to last).

 - Function: get-window-by-id xid
     Return a window object with id XID, or `nil'.

 - Function: get-window-by-name name
     Return a window object with name NAME, or `nil'.

Window Property Lists
=====================

   Many window manager extensions need to be able to associate Lisp data
with individual windows. For example, the module handling iconification
needs to associate a boolean value with each window--whether that
window is iconified or not.

   To solve this problem, Sawfish gives each window a property list.
These are exactly analogous to the property lists stored with each
symbol (see Property Lists (librep)); they allow
values to be associated with Lisp symbols, for a particular window.

   Note that these properties are different to the properties that X
stores with each window, since these properties are internal to the
window manager (see X Properties).

 - Function: window-put window property value
     Set the lisp property named PROPERTY (a symbol) associated with
     window object WINDOW to VALUE.

 - Function: window-get window property
     Return the window property named PROPERTY associated with the
     window object WINDOW, or `nil' if no such property exists.

   For a list of the standard window properties, see Standard Properties.

Window Attributes
=================

 - Function: window-name window
     Return the name associated with WINDOW.

 - Function: window-full-name window
     Return the full-name associated with WINDOW. This may or may not
     be the same as the normal name.

 - Function: window-icon-name window
     Return the icon name associated with WINDOW.

 - Function: window-mapped-p window
     Return `t' if the client window associated with object WINDOW is
     mapped. (Note that this doesn't necessarily mean that it is
     visible.)

 - Function: window-transient-p window
     Returns `nil' if WINDOW isn't marked as a transient window.
     Otherwise returns an integer, the xid of the parent window.

 - Function: window-shaped-p window
     Return `t' if WINDOW is shaped (possibly not rectangular).

 - Function: window-id window
     If window object WINDOW has a client window associated with,
     return an integer defining its xid, otherwise return `nil'.

 - Function: window-group-id window
     Return an integer defining the xid of the leader of the group that
     WINDOW is a member of, or `nil' if WINDOW is not a member of a
     group.

 - Function: window-wants-input-p window
     Return `t' when the client window associated with object WINDOW
     has asked for the input focus to be assigned to it when applicable
     (through the `input' field of its `WM_HINTS' property).

 - Function: window-dimensions window
     Returns a cons cell `(WIDTH . HEIGHT)' defining the dimensions of
     the client window associated with object WINDOW.

 - Function: window-position window
     Returns a cons-cell `(X . Y)' defining the position relative to
     the root window of WINDOW.

 - Function: window-size-hints window
     Return an alist defining the size-hints structure specified by the
     client window associated with WINDOW. Possible keys in the alist
     are `min-height', `max-height', `min-width', `max-width',
     `height-inc', `width-inc', `min-aspect', `max-aspect',
     `base-height', `base-width', `user-position', `program-position',
     `user-size', `program-size', `window-gravity'.

 - Function: window-visibility window
     Returns a symbol defining the current visibility of WINDOW.
     Possible returned symbols are `fully-obscured',
     `partially-obscured' or `unobscured'.

Input Focus
===========

   The input focus defines exactly which client window will receive
events generated by the keyboard.

 - Function: input-focus
     Returns the window object of the currently focused window, or
     `nil' if no window is focused.

 - Function: set-input-focus window
     Sets the focus to the client window associated with WINDOW.

 - Variable: focus-mode
     Defines the current method of using the mouse to assign the input
     focus. Possible values are `enter-exit', `enter-only' and `click'.

 - Variable: focus-proxy-click
     When in click-to-focus mode, the focus-assigning click is only
     passed through to the client window if this variable is non-`nil'.

     This option may be set on a per-window basis by setting the
     `focus-click-through' property of the window (using the
     `window-put' function).

   Sawfish also maintains the order in which windows were recently
focused.

 - Function: window-order &optional workspace allow-iconified
          all-viewports
     Return a list of windows, in most-recently-focused order.

     If WORKSPACE is an integer, then only windows on that workspace
     are included, otherwise all workspaces are searched.

     If ALLOW-ICONIFIED is non-nil, iconified windows are included. If
     `all-viewports' is non-nil, then all viewports of the workspace(s)
     are scanned.

 - Function: window-order-push window
     Push window object WINDOW onto the top of the focus stack.

 - Function: window-order-pop window
     Remove window object WINDOW from the focus stack.

 - Function: window-order-focus-most-recent
     Focus the most-recently-focused window on the current viewport of
     the current workspace.

X Properties
============

   The X window system associates properties with windows (these are
totally separate to the properties that sawfish associates with window
_objects_, see Window Property Lists). Most inter-client
communication is performed through manipulation of these properties.

   All functions defined below, that operate on X properties, accept
their WINDOW parameter as either a window object (denoting the
associated client window), the numeric xid of a window, or the symbol
`root' denoting the root window.

   Sawfish represents X atoms (both the names and data types of  X
properties) as symbols. There is an exact correspondence between the
names of atoms and the name of the symbol representing them. For
example, the X atom `STRING' is represented by the lisp symbol `STRING'.

 - Function: list-x-properties window
     Return a list of symbols defining the X properties set on WINDOW.

 - Function: delete-x-property window property
     Deletes the X property named PROPERTY (a symbol) associated with
     WINDOW.

 - Function: get-x-property window property
     Returns a list `(TYPE FORMAT DATA)' representing the X property
     PROPERTY of WINDOW. If no such property exists, return nil.

     TYPE is the atom defining the type of the property. FORMAT is an
     integer, either 8, 16 or 32, defining the number of bits in each
     of the data items. DATA is an array, either a string for an 8-bit
     format property, or a vector of integers otherwise.

     If TYPE is `ATOM' and FORMAT is 32, then DATA will be a vector of
     symbols, representing the atoms read.

 - Function: set-x-property window property data type format
     Set the X property PROPERTY of WINDOW to the array DATA, either a
     string or a vector of integers.

     TYPE is a symbol representing the atom defining the type of the
     property; FORMAT is either 8, 16 or 32 defining the number of bits
     in the data values.

     If TYPE is `ATOM' and FORMAT is 32, then any symbols in DATA will
     be converted to their numeric X atoms.

   The standard X property formats don't allow for an array of strings
to be stored, so these are often encoded as the strings concatenated,
separated by zero characters. These are usually called "text
properties". Sawfish has two functions for manipulating them:

 - Function: get-x-text-property window property
     Similar to `get-x-property', but returns either `nil' or a vector
     of strings.

 - Function: set-x-text-property window property data
     Sets the X text property PROPERTY of WINDOW to the array of
     strings DATA.

   It's also possible to detect when the value of any property
associated with a managed window changes, using the
`property-notify-hook'.  See Standard Hooks.

Window Stacking
===============

   The stacking order of the display defines the order in which windows
are shown, from topmost to bottommost.

 - Function: stacking-order
     Return a list of window objects defining the current stacking
     order of all client windows, from top-most to bottom-most.

 - Function: restack-windows list
     Restack all client windows specified in the list of window objects
     LIST in the order they occur in the list (from top to bottom).
     The stacking order of any unspecified windows isn't affected.

 - Function: x-raise-window window
     Raise the client window associated with object WINDOW to the top
     of the display.

   Sawfish allows the stacking order to be managed as a sequence of
layers, with windows being assigned a particular depth within the
order. For any given window with depth D, it will be above all windows
with depth less than D, and below all windows with depth greater than
D. It may be above or below any other windows with depth D.

   The `depth' property of each window is used to store this depth. A
depth of zero is "normal", with negative depths stacked below, and
positive depths stacked above this normal level.

 - Function: stacking-order-by-depth depth
     Similar to `stacking-order', but only returns windows with depth
     DEPTH.

 - Function: set-window-depth window depth
     Set the stacking depth of WINDOW to DEPTH, then restacks the
     windows to reflect this change.

 - Function: window-on-top-p window
     Returns `t' if WINDOW is at the top of its stacking depth.

 - Function: stack-window-below below above
     Change stacking order of window BELOW so that it is immediately
     below window ABOVE.

 - Function: stack-window-above above below
     Change stacking order of window ABOVE so that it is immediately
     above window BELOW.

 - Macro: save-stacking-order &rest forms
     Evaluate FORMS in an implicit `progn', then restore the original
     window stacking order, returning the value of the `progn'.

   For the following functions, when called interactively they all
operate on the window that received the current event, or alternatively
the currently focused window.

 - Command: lower-window window
     Lower WINDOW to the bottom of its stacking depth.

 - Command: raise-window window
     Raise WINDOW to the top of its stacking depth.

 - Command: raise-lower-window window
     If WINDOW is the highest in its stacking level, lower it to the
     bottom of this level, otherwise raise it to the top of its level.

 - Command: lower-window-depth window
     Decrement the stacking depth of WINDOW.

 - Command: raise-window-depth window
     Increment the stacking depth of WINDOW.

Moving and Resizing Windows
===========================

   As noted above (see Window Attributes), the `window-dimensions'
and `window-position' functions return the current configuration of a
window.

 - Function: move-window-to window x y
     Move the top-left corner of the window frame of WINDOW to (X, Y).

 - Function: resize-window-to window width height
     Set the dimensions of the client window associated with object
     WINDOW to (WIDTH, HEIGHT).

 - Function: move-resize-window-to window x y width height
     A combination of the previous two functions.

 - Function: resize-window-with-hints window cols rows &optional hints
     Resize the window associated with object WINDOW so that it has
     COLS columns and ROWS rows. The HINTS parameters is either the
     size hints alist to use, or `nil' in which case the
     `window-size-hints' function is used to retrieve the window's
     hints.

   Usually, however, it is left to the user to configure windows. The
following functions may be called interactively: their sole argument is
then either the window that received the current event or the currently
focused window.

 - Command: move-window-interactively window
     Move WINDOW interactively using the mouse. Releasing any mouse
     button places the window at its current position.

 - Command: resize-window-interactively window
     Resize WINDOW interactively using the mouse. Releasing any mouse
     button places the window at its current position.

     Note that this function selects the edge or edges of the window to
     move from the current position of the mouse when the resizing
     begins. The window is divided into a three-by-three grid; the
     rectangle containing the mouse pointer gives the direction to
     resize in. If the pointer is in the central rectangle the bottom
     and right edges are moved.

 - Command: move-selected-window
     Wait for the user to select a window using the mouse, then
     interactively move that window.

 - Command: resize-selected-window
     Wait for the user to select a window with the mouse, then
     interactively resize that window.

   The interactive move and resize behavior can be customized through
the following variables:

 - Variable: move-outline-mode
     A symbol defining the visual method of interactively moving
     windows.  Current options include `box' for a wire-frame grid, and
     `opaque' for full redisplay.

 - Variable: resize-outline-mode
     A symbol defining the visual method of interactively resizing
     windows.  Current options include `box' for a wire-frame grid, and
     `opaque' for full redisplay.

 - Variable: move-show-position
     When non-nil, the current window position is shown in the center
     of the screen.

 - Variable: resize-show-position
     When non-nil, the window size is shown in the center of the screen.

 - Variable: move-snap-edges
     When non-nil, the window position is "snapped" to edges of other
     windows within close proximity.

 - Variable: move-snap-epsilon
     The distance in pixels before snapping together two edges.

Showing and Hiding Windows
==========================

   Sawfish provides two low-level functions for withdrawing client
windows from the display. These are used to implement both virtual
workspaces (see Workspaces) and iconification (see Iconifying Windows).

 - Function: hide-window window
     Prevent object WINDOW from being displayed.

 - Function: show-window window
     Ensure that WINDOW (if it has been mapped, and is within the
     screen boundary) is visible.

 - Function: window-visible-p window
     Returns `t' if object WINDOW has not been hidden by the
     `hide-window' function.

Destroying Windows
==================

   There are several methods through which X11 client windows may be
removed from the display. These differ in the level "politeness" they
show the window and its owning application.

 - Command: delete-window window
     Delete WINDOW, i.e. send a `WM_DELETE_WINDOW' client-message if
     possible, or just kill the associated X11 client if not.  WINDOW
     may be a window object or a numeric window id.

 - Command: delete-window-safely window
     If the application owning WINDOW supports it, send a
     `WM_DELETE_WINDOW' message to WINDOW. Otherwise just emit a beep.

 - Command: destroy-window window
     Destroy WINDOW without giving the owning application any warning.
     WINDOW may be a window object or a numeric window id.

 - Function: x-kill-client window
     Force a close down of the X11 client that created the window
     specified by WINDOW (a window object, or numeric id).

   When a managed window is destroyed, the `destroy-notify-hook' will
subsequently be invoked (see Standard Hooks).

Shading Windows
===============

   Many window managers allow a window to be "shaded"; when in this
state only the title bar of the window is visible.

 - Command: shade-window window
     Arrange for only the title bar of WINDOW to be visible.

 - Command: unshade-window window
     If the window is shaded, restore it to it's original state.

 - Command: toggle-window-shaded
     Toggle the shaded state of the window.

   The `shaded' property of a window is set to `t' when the window is
shaded. If a window is added with this property already set, then the
window will appear in its shaded state.

Iconifying Windows
==================

   X defines an iconic state for windows, often windows in this state
are displayed as small icons. Sawfish does not display these icons,
instead iconified windows are shown slightly differently in the menu of
all windows.

 - Command: iconify-window window
     Iconify the window associated with object WINDOW.

 - Command: uniconify-window window
     Return the window associated with WINDOW from its iconified state.

   A window's iconic state may be tested through examination of its
`iconified' property--when `t' the window is iconified.

Maximizing Windows
==================

   The dimensions of a window may be temporarily "maximized".

 - Command: maximize-window window &optional direction
     Maximize both dimensions of WINDOW

     If defined, DIRECTION may be either `vertical' or `horizontal'.

 - Command: maximize-window-vertically window
     Maximize the vertical dimension of WINDOW.

 - Command: maximize-window-horizontally window
     Maximize the horizontal dimension of WINDOW.

 - Command: unmaximize-window window &optional direction
     Restore the dimensions of WINDOW to its original, unmaximized,
     state.

     If defined, DIRECTION may be either `vertical' or `horizontal'.

 - Command: maximize-window-toggle window
     Toggle the state of WINDOW between maximized and unmaximized.

     If defined, DIRECTION may be either `vertical' or `horizontal'.

 - Command: maximize-window-vertically-toggle window
     Toggle the state of WINDOW between vertically maximized and
     unmaximized.

 - Command: maximize-window-horizontally-toggle window
     Toggle the state of WINDOW between horizontally maximized and
     unmaximized.

 - Function: window-maximized-p window
     Return `t' when WINDOW is in the maximized state.

 - Function: window-maximized-vertically-p window
     Return `t' when WINDOW is vertically maximized.

 - Function: window-maximized-horizontally-p window
     Return `t' when WINDOW is horizontally maximized.

Customization
*************

   Sawfish provides two levels of configuration:

  1. "customization": setting variables to change the behavior of
     existing features of the window manager, and,

  2. "extensibility": the ability to add entirely new features to the
     window manager through the creation of new Lisp modules.

   Obviously the first of these requires a lot less specialized
knowledge than the second. But even then, the user has to edit startup
files containing the Lisp forms setting the variables. To remove this
need for hand-editing, Sawfish has a specialized system allowing all
customizations to be made through a GUI, and then automatically
reloaded each time that the window manager is started.

 - Command: customize &optional group
     Invoke the user-customization GUI. GROUP defines the class of
     customization variables to configure, or all classes if GROUP is
     undefined.

   The `sawfish-ui' program can be used to invoke the GUI manually; if
GNOME is being used, then the GNOME Control Center can also be used to
customize certain classes.

   In order to provide these customization options however, an extra
requirement is placed on the Lisp programmer. Instead of just using the
`defvar' special form to declare variables, the `defcustom' macro must
be used. This augments the variable with extra information for the GUI,
including such things as its required data type.

   Customization options are organized into groups. Each group has a
name and contains a set of related options. Currently, it is not
possible for groups to contain sub-groups.

 - Macro: defgroup group real-name &rest keys
     Declares a new customization group whose name is defined by the
     symbol GROUP. The string REAL-NAME is the title of the group as
     seen by the user.

     KEYS is a list, defining the properties of the group. The members
     of the list are grouped into pairs of elements, the first element
     names the property, the second defines its value. Currently the
     only property is `:widget', defining a function to create the
     group's UI widget.

     This macro also creates an interactive function named
     `customize:GROUP' allowing the GUI to be invoked to configure the
     new group.

 - Macro: defcustom variable value documentation &rest keys
     The first three arguments are analogous to the `defvar' special
     form, they declare a special variable stored in the symbol
     VARIABLE, whose value is set to VALUE if the variable is currently
     unbound, with a documentation string DOCUMENTATION.

     All other parameters are key-value pairs as with `defgroup'. The
     possible pairs are as follows:

    `:group GROUP'
          Specifies the customization group that this variable is a
          member of.

    `:type TYPE'
          Specifies the required type of the variable. The current
          possibilities are `boolean', `number', `string', `file-name',
          `program-name', `font', `color', `frame-style', `keymap' and
          `(set SYMBOLS...)'.

          The `boolean' type assures a value of either `nil' or `t',
          the `set' type allows the user to choose from one of the
          symbols in the list.

    `:require FEATURE'
          Denotes that the feature FEATURE must be loaded if the
          variable is set to a non-`nil' value by user customizations.
          This is necessary because customization options are loaded on
          startup, possibly before the modules that define them.

    `:allow-nil BOOL'
          Specifies whether the variable may be `nil', instead of a
          member of its actual type. This is only supported by the
          `string', `set', `font' and `color' types.

    `:set FUNCTION'
          Specifies that the variable must be set by calling FUNCTION
          instead of the default `custom-set-variable'. The function
          should accept three arguments: `(VARIABLE VALUE &optional
          REQUIRE)'.

          The usual action of this function is to translate the value
          into the correct type, then call `custom-set-variable'. This
          translation is necessary since many of the UI widgets accept
          strings representing more complex types (i.e. a color's name,
          instead of the actual object)

    `:get FUNCTION'
          Provides a function for reading the current value of the
          variable.  Should return a value that's acceptable to the UI
          widget associated with the variable. Called with a single
          argument, the symbol containing the variable.

    `:before-set FUNCTION'
    `:after-set FUNCTION'
          Functions called both immediately before and after setting
          the value of the variable. Called with a single parameter:
          the variable itself.

    `:range (MIN . MAX)'
          The allowed range for numeric variables. If MIN is `nil' the
          the default minimum allowed value is zero; if MAX is `nil'
          then the default maximum is unbounded.

   Note that where necessary the types themselves define default
`:set', `:get' and `:widget' values that may be overridden by values in
the `defcustom' call. Usually, however, this will not be necessary.

   Consider the following example:

     (defgroup move "Move/Resize")

     (defcustom move-outline-mode 'opaque
       "The method of drawing windows being moved interactively."
       :type (set opaque box)
       :group move)

     (defcustom move-snap-epsilon 8
       "Proximity in pixels before snapping to a window edge."
       :group move
       :type number
       :range (0 . 64))

This defines a group and two customization options.

Window Frames
*************

   Perhaps one of the most important features of a window manager is its
ability to decorate client windows, typically seen as an added border,
and then to allow the window to be manipulated through user input on
the border.

   Sawfish provides an extremely flexible method of decorating windows,
the look and feel of the border may be specified completely. Also, no
limits are placed on which windows are given which borders, if
necessary a completely different border could be dynamically created
for each window!

Frame Basics
============

   The "frame" of a client window is defined as all decorations added
by the window manager. Usually these decorations will be immediately
adjacent to the outer edges of the window, but there is no requirement
to use this model.

   In Sawfish, each window frame is constructed from a list of "frame
parts", conceptually rectangular objects with a specified position
relative to the edges of the client window. When shaped images are used
to define frame parts, they are still thought of as being rectangular,
just with some pixels missing from the display.

   Each frame part has a list of attributes associated with it, these
include items defining the background of the part (i.e. a color or an
image), and items defining the foreground of the part (i.e. probably
some kind of text, with a color, font, etc...). Non-visual attributes
may also be defined, such as, for example, the keymap mapping events
occurring in the part to Lisp commands to execute (see Keymaps).

   So a window frame is defined in Lisp as a list of frame part
definitions (see Frame Part Definition). These frame parts are
added to the client window (in the order they are defined, so later
frame parts are above earlier parts at the same position), to produce
the entire window frame.

Frame Part Classes
==================

   Although one of the aims of Sawfish is to provide as much flexibility
as possible, this can sometimes be detrimental to the overall
experience. For example, it would be easier for the user if all themes
use consistent keymaps and cursor images in conceptually similar parts
of window frames. That is, it would be better if all close buttons had
the same mouse button bindings and the same mouse cursor displayed when
the pointer is over them.

   To achieve this, Sawfish defines a number of "classes" of frame
parts, each with several default attributes. When defining a window
frame, the definitions of each part then specifies which class it is a
member of, and inherits the associated default attributes (provided
that it hasn't explicitly specified values for these attributes).

 - Variable: frame-part-classes
     This variable is an association list, associating symbols naming
     frame part classes with an association list of default attributes
     for that class.

   The names of the pre-defined classes are as follows, their meanings
should be self-explanatory:

   `title', `menu-button', `close-button', `iconify-button',
`maximize-button', `top-border', `left-border', `right-border',
`bottom-border', `top-left-corner', `top-right-corner',
`bottom-left-corner', `bottom-right-corner'.

Extra classes can be created by adding to `frame-part-classes'.
However, it's likely that more than one theme may need to use the same
class, and that the user may then wish to customize any extra keymaps
used. The `def-frame-class' macro should be used to add new classes,
since it handles these situations.

 - Macro: def-frame-class class alist-form &rest binding-forms ...
     Creates a new frame part class named by the symbol CLASS.

     The ALIST-FORM is evaluated to give an association list defining
     attributes for the class. Each key-value pairs is only set if no
     existing value exists for that key.

     If BINDING-FORMS are given, they will be evaluated when no keymap
     already exists for the class. A keymap will be created, and stored
     in the variable named `CLASS-name'. This variable may then be used
     withing the BINDING-FORMS.

   So to define a hypothetical `shade-button' class, the following
might be used:

     (def-frame-class shade-button '((cursor . left_ptr))
       (bind-keys shade-button-keymap
         "Button1-Off" 'toggle-window-shaded))

   In some cases it might be valuable to be able to override pre-defined
frame part properties. For example, it might be your preference that
text in window title bars is always blue.

 - Variable: override-frame-part-classes
     Similar to `frame-part-classes' except that the properties take
     precedence over values defined both in that variable and in the
     frame style itself.

   The following function may be used to simplify the customization of
these two variables:

 - Function: set-frame-part-value class key value &optional override
     Associate VALUE with property KEY for all frame parts of class
     CLASS.

     If OVERRIDE is non-nil, then the setting is installed in the
     `override-frame-part-classes' variable, otherwise it's stored in
     the `frame-part-classes' variable.

The following example would override the colors of all title bars:

     (set-frame-part-value 'title 'background
                           '("black" "white" "green" "blue") t)

(See the next section for details about what is actually being set
here.)

Frame Part Definitions
======================

   Each frame part is defined as an association list (or alist), a list
of cons cells, the car of each cell defines the attribute, the cdr
defines the value given to that attribute. So, for example, the alist
`((foo . 1) (bar . 2))' specifies two attributes: `foo' with value `1',
and `bar' with value `2'. See Association Lists (librep).

   The attributes that may be defined are as follows:

`(class . CLASS)'
     Specifies the frame part class of the part.

`(background . DATA)'
`(background . (NORMAL FOCUSED HIGHLIGHTED CLICKED))'
     Specifies the background of the part. May be a color, an image, or
     a string naming a color. If a single element, then it is used for
     all states of the part, otherwise if a list, then each of the four
     elements defines the background for that particular state.

     If an image is used it will be scaled to the size of the frame
     part, unless it's `tiled' property is set, in which case it will be
     tiled across the frame part.

`(foreground . DATA)'
`(foreground . (NORMAL FOCUSED HIGHLIGHTED CLICKED))'
     Specifies a foreground color or image for the frame part, either
     for all states, or for each individual state.

     Unlike the `background' attribute, by default images are not
     scaled when used to define the foreground of a frame part.

`(scale-foreground . VALUE)'
     When VALUE is non-`nil', the foreground image of the frame part
     will be scaled to the size of the part.

`(font . FONT)'
`(font . (NORMAL FOCUSED HIGHLIGHTED CLICKED))'
     Specifies the font(s) of the part.

`(text . VALUE)'
     Specifies the string to draw in the foreground of the frame part
     (unless the `foreground' property is an image). Either a string,
     or a function, that will be called each time that the part is
     refreshed, that will return the string to draw.

`(x-justify . VALUE)'
     Defines the horizontal position of the foreground contents of the
     part (i.e. the text or foreground image). May be one of the symbols
     `left', `right' or `center', or a number. If a number it defines
     the number of pixels from the left edge if positive, or the right
     edge if negative.

`(y-justify . VALUE)'
     Similar to `x-justify', but the accepted symbols are `top',
     `bottom' or `center' instead.

`(renderer . FUNCTION)'
     This attribute may be used instead of the `background' attribute.
     When the part needs to be drawn FUNCTION will be called with an
     image in which to render the background, and the current state of
     the part, a symbol `focused', `highlighted', `clicked', or `nil'
     (for the normal state).

`(render-scale . VALUE)'
     This attribute causes the size of the image used with the
     `renderer' property to be reduced by a factor of VALUE, an integer.

`(left-edge . VALUE)'
     Defines the position of the left edge of the part, in relation to
     the left edge of the client window.

`(right-edge . VALUE)'
     Defines the position of the right edge of the part, in relation to
     the right edge of the client window.

`(top-edge . VALUE)'
     Defines the position of the top edge of the part, in relation to
     the top edge of the client window.

`(bottom-edge . VALUE)'
     Defines the position of the bottom edge of the part, in relation
     to the bottom edge of the client window.

`(width . VALUE)'
     Defines the width of the frame part.

`(height . VALUE)'
     Defines the height of the frame part.

`(keymap . VALUE)'
     Defines the keymap to use when evaluating events originating in
     this frame part.

`(cursor . CURSOR)'
     Defines the cursor to display when the mouse is in this part. May
     be either a cursor object, or the argument to `get-cursor' to
     create the required cursor object.

`(removable . VALUE)'
     When specified and VALUE is non-`nil', this frame part may be
     removed from the frame without being detrimental to the overall
     appearance of the frame. This is only important for button classes,
     which may sometimes be removed at the request of the client window.

`(below-client . VALUE)'
     When specified and VALUE is non-`nil', then this frame part will
     be displayed beneath the client window. The default action is for
     frame parts to be stacked above the client window.

`(hidden . VALUE)'
     When specified and VALUE is non-`nil', don't display this frame
     part.

   The values specified for the `background', `foreground',
`render-scale', `font', `left-edge', `right-edge', `top-edge',
`bottom-edge', `width', `height', `cursor', `below-client' and `hidden'
attributes may actually be functions. In which case the function will
be called (with a single argument, the window object) when the frame is
constructed, the value returned will be used as the actual value of the
attribute.

   The coordinate system used for specifying the part's position is
relative to the window edge that the position is defined against.
Positive values count in from the window edge towards the center of the
window, while negative values count out from the edge, away from the
center of the window.

   Consider the following example, a solid black title bar that is
twenty pixels high, directly above the client window:

     `((background . "black")
       (foreground . "white")
       (text . ,window-name)
       (x-justify . 30)
       (y-justify . center)
       (left-edge . 0)
       (right-edge . 0)
       (top-edge . -20)
       (height . 20)
       (class . title))

The backquote operator is used since the definition is only mostly
constant, the comma operator inserts the value of the `window-name'
variable (a function giving the name of a window) into the definition;
see Backquoting (librep)).

   This function is then used to dynamically specify the string drawn in
the foreground. The window manager will automatically refresh the
foreground of all frame parts of a window whenever any X property of
that window changes.

   Given a framed window, and a particular frame part class, it is
possible to retrieve the values of individual attributes from the
complete list of definitions (including inherited or overrided
definitions).

 - Function: frame-part-get window class attr
     Returns the value of the attribute ATTR for the frame part of
     class CLASS in the current frame of WINDOW.

     Returns `nil' if no such attribute exists. If more than one frame
     part of class CLASS exists then the value will be taken from the
     first part found.