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.

This document describes the Lisp programming interface to sawfish, an extensible X11 window manager.

This is Edition 0.6 of its documentation, last updated 12 December 1999 for Sawfish version 0.19.

Copying
*******

Sawfish is copyright (C) 1999 John Harper and is released under the terms of the GNU General Public License. See the included file COPYING for the full text of the license (or see Copying (The GNU Emacs Manual)).

     This is free software -- you are welcome to redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

     Sawfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

Introduction
************

Sawfish is a lisp-extensible window manager for X11. Its aim is to allow all areas of window management (decoration, manipulation) to be customized as far as is possible, yet still remain as fast or faster than existing window managers.

Despite this extensibility its policy is very minimal compared to most window managers. It does not implement desktop backgrounds, applications docks, or other things that may be achieved through separate applications.

All high-level window management functions are implemented in Lisp for future extensibility or redefinition. Also, most received events are exported to the Lisp environment through key-bindings and hooks, similar to in Emacs. These events include pointer behavior and many internal X11 events.

Sawfish uses the librep Lisp environment (see Overview (The Librep Manual)), this is a run-time library implementing a language similar to Emacs Lisp (see Overview (The Emacs-Lisp Manual)), but with many extensions, and using lexical instead of dynamic scope. This manual assumes at least a basic knowledge of the language.

     [file news.texi not included]

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 (The Librep Manual)); 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 (The Librep Manual).

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 (The Librep Manual)).

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.

Frame Functions
===============

 -- Function: set-window-frame window frame-def
     Sets the frame of the client window associated with the object WINDOW to that defined by the list of frame part definitions FRAME-DEF. If the window is mapped the old frame will be destroyed and a new frame constructed.

 -- Function: window-frame window
     Return the list of frame part definitions defining the frame associated with WINDOW.

 -- Function: window-framed-p window
     Return t when WINDOW has been reparented to a frame created by the window manager.

 -- Function: rebuild-frame window
     Recreates the window frame associated with WINDOW, from the previously defined frame definition. All frame parts are reinitialized and recalibrated.

 -- Function: window-frame-dimensions window
     Return a cons cell (WIDTH . HEIGHT) defining the dimensions of the frame associated with WINDOW. These will always be greater than or equal to the dimensions of the client window.

     If WINDOW is not framed, then this function returns the same values as window-dimensions would.

 -- Function: window-frame-offset window
     Return a cons cell (X . Y) defining the offset from the origin of the client window associated with WINDOW to the origin of its frame.

Frame Types
===========

In order to visually differentiate between different types of windows, several predefined types of window frame exist. These types currently include the following:

default
     The normal frame type. Includes all decorations, both borders and the title bar.

transient
     The frame for a transient window. This usually does not include a title bar, but does have all four borders.

shaped
     Shaped windows are normally decorated with only a title-bar, since their boundary is not rectangular it makes no sense to surround them with a rectangular border.

shaped-transient
     A combination of the shaped and transient types, normally just a very small title border with no text.

shaded
     A shaded window (normally just the title bar).

shaded-transient
     A shaded transient window.

unframed
     No frame at all, just the client window itself. The predefined nil-frame variable contains a null frame that may be used for this frame type.

The type of frame that would ideally be given to a window is stored in the window's type property. It should usually be accessed through the window-type function:

 -- Function: window-type window
     Returns a symbol naming the frame type currently associated with WINDOW.

Frame Styles
============

Frame styles are used to encapsulate frames of the different types that have a single visual appearance. Each frame style associates a name with a function that creates a frame definition for a particular window and frame type combination.

 -- Function: add-frame-style name function
     Defines a new frame style called NAME (a symbol). When a frame of this style is required for a particular window, FUNCTION is called with two arguments, the window itself and a symbol defining the frame type to create (see Frame Types).

     If the frame style is unable to provide a frame definition of the required type, it should return the symbol nil. In which case it may subsequently be asked for a frame of a different type.

     If no default frame style exists, the new style will be made the default.

 -- Variable: default-frame-style
     A symbol naming the frame style to use for windows where no other style is explicitly specified.

 -- Function: check-frame-availability name
     Returns t if a frame style called NAME exists. Will try to load such a frame from the filing system if necessary.

 -- Function: set-window-frame-style window style &optional type from-user
     Sets the frame of WINDOW to the style named by the symbol STYLE. If TYPE is defined then it names the frame type to use, otherwise the default type for this window is used.

     If FROM-USER is non-nil then the user chose this frame style for the window explicitly (i.e. it's not just the default choice for a new window).

 -- Function: set-frame-for-window window &optional force type
     If WINDOW has no frame style associated with it, then chooses the default value for this window, the value of default-frame-style.

     If FORCE is non-nil then the style is always re-chosen, even if the window already has a chosen default style.

     If TYPE is non-nil it defines the frame type to give the window, otherwise the current default for the window is used.

 -- Function: reframe-all-windows
     Forcibly reselect all window frame styles. Only windows with a user specified style are not changed to the current defaults.

 -- Function: rebuild-frames-with-style style
     Call rebuild-frame on all windows that currently have a frame defined by frame style STYLE (a symbol)

 -- Function: reframe-windows-with-style style
     Completely recreate all window frames that are defined by the style STYLE.

Several window properties are used while choosing frame styles:

 -- Window Property: frame-style
     The user-chosen frame style of the window, or nil.

 -- Window Property: current-frame-style
     The current frame style of the window.

 -- Window Property: ignored
     When set, the window is not given a frame.

Themes
======

Themes and frame styles are currently almost synonymous, the slight difference being that themes provide a mechanism for loading frame styles from the filing system as they are required. Although it is possible that themes may include other user-interface settings in a later version, at the moment it seems unlikely.

When a frame style is requested, if it is not already available (i.e. if the add-frame-style function hasn't been called for that style) then the window manager will attempt to load a theme of the same name from the filing system.

Each theme is stored in a directory; this directory must have the same name as the name of the theme itself. Within this directory there must be a Lisp script named theme.jl or theme.jlc. This script will be evaluated, it should provide a frame style of the same name as the theme (by calling add-frame-style).

While the theme script is evaluating the image-load-path variable is set to include the theme directory as its first element. This ensures that any image files stored in the directory can be loaded using the make-image function.

Since rep has no module system, any global variables defined within the theme must be prefixed by the name of the theme to ensure their uniqueness. For example, in the theme foo, a variable bar would actually be called foo:bar.

In most cases however, rep's lexical scoping can be used to avoid declaring any global variables or functions, the only usual exception is when declaring customization options with defcustom; these must be globally visible.

Since themes are generally passed around very casually, sawfish evaluates all theme code in a very restricted environment; the idea being that themes should only be able to affect the look of the window manager. Despite this, it is still possible for malicious themes to lock, and possibly crash, the window manager; in the first case sending a SIGINT signal may unblock it. Hopefully themes are unable to affect the rest of the user's environment, but there are no guarantees...

 -- Variable: theme-load-path
     A list of directory names, provides the search path for locating theme directories. By default this includes the user's theme directory and the system theme directory.

 -- Variable: user-theme-directory
     The name of the user's theme directory, by default ~/.sawfish/themes.

 -- Variable: system-theme-directory
     The name of the system theme directory.

Removing Frame Parts
====================

It is often useful to be able to disable certain parts of a window's frame. For example, a window may hint to the window manager that it doesn't want a maximize button. Sawfish allows all parts of a particular class to be disabled or enabled on a window by window basis. However, not all frame styles will support this (it depends on the frame part's removable property, Frame Part Definition).

 -- Function: remove-frame-class window class
     Disable all frame parts that are a member of CLASS in WINDOW where possible.

 -- Function: add-frame-class window class
     Enable all frame parts that are a member of CLASS in WINDOW.

Workspaces
**********

XXX what do I want to say here?

Popup Menus
***********

Popup menus are one of the two main methods through which the user may invoke Lisp code (the other is via keymaps, see Keymaps). The popup-menu function is invoked with a list of menu item definitions and the associated Lisp function to call for each item. This starts a subprocess to display the menu, then at a later date the chosen menu item is received and evaluated.

Each menu item is specified by a list, the first element of which is a string providing the label for the menu item, the second element is a function to be called if that item is selected by the user. If this function has an interactive specification it will be invoked using the call-command function, otherwise funcall will be used. Alternatively the second element may be a lisp form to evaluate. So, for example, a single-level menu could be defined by:

     (("Item 1" function-1)
      ("Item 2" function-2)
      ()
      ("Item 3" function-3))

The null item will create a separator line in the displayed menu.

If the cdr of first element of any item is a symbol, then the rest of the item is defined by the value of the named variable. If this value is functional then the definition is found by calling the function.

Consider the following definition:

     (("Workspaces" . workspace-menu)
      ("Windows" . window-menu)
      ("Programs" . apps-menu)
      ("Customize" . custom-menu)
      ("About..." (customize 'about))
      ()
      ("Restart" restart)
      ("Quit" quit))

This is the definition of Sawfish's root menu. We can see that four submenus are created dynamically by dereferencing variables (in fact, three of this variables contain functions) (workspace-menu, window-menu, apps-menu and custom-menu). Note that these must be special variables, i.e. initially declared using the defvar special form.

The apps-menu variable can thus be used to redefine the applications menu. The default definition is as follows:

     (("xterm" (system "xterm &"))
      ("Emacs" (system "emacs &"))
      ("Netscape" (system "netscape &"))
      ("The GIMP" (system "gimp &"))
      ("XFIG" (system "xfig &"))
      ("GV" (system "gv &"))
      ("xcalc" (system "xcalc &")))

The system function simply executes its single argument using /bin/sh.

 -- Function: popup-menu spec
     Displays a menu defined by the list of item definitions SPEC.

 -- Function: popup-window-menu
     Display the menu listing all window operations.

 -- Function: popup-root-menu
     Display the main menu.

 -- Function: popup-apps-menu
     Displau the applications menu.

 -- Variable: root-menu
     Contains the root menu definition.

 -- Variable: apps-menu
     The variable containing the definition of the applications submenu of the root menu.

Since the overhead of starting the menu subprocess may be noticeable on some systems, it is possible to leave it running between menu requests.

 -- Variable: menu-program-stays-running
     This variable defines if, and for how long, the menu subprocess is allowed to remain executing for after the last menu has completed. If nil, the program is terminated immediately, if t it is left running indefinitely, if an integer then the program will run for that many seconds (unless another menu is displayed).

Events
******

Events refer to input events from X that the window manager receives, either for the root window, the window frames it creates, or grabbed from the client windows themselves. Each event induced by the mouse or keyboard has a Lisp representation.

Each input event is represented by a cons cell containing two integers, these integers encode the actual input event. The encoding is opaque; the only way to access an event meaningfully is via the functions provided.

 -- Function: eventp object
     This function returns t if its argument is an input event.

Each event has a name, a string. This string contains zero or more modifier descriptions separated by hyphens, and then the name of the key itself. The standard X modifier names are provided, as well as three special modifiers Meta, Alt and Hyper that are mapped to the keysyms of the same name.

The following table lists the possible modifier prefixes:

C
     The control modifier

M
     The meta modifier

A
     The alt modifier

S
     The shift modifier

H
     The hyper modifier

ModK
     The standard X modifiers, for K between 1 and 5

ButtonK
     The K'th mouse button is currently pressed

Note that the M and A modifiers are virtual modifiers assigned dynamically, according to the X server's xmodmap configuration. The A virtual modifier is assigned to the X modifier with either the Alt_L or Alt_R keysym assigned to it. The M virtual modifier is assigned to the X modifier with either Meta_L or Meta_R assigned to it. If either of these two virtual modifiers would be unassigned it is set identically to the other virtual modifier.

There are two special modifiers: the Any prefix matches any set of modifiers; the Release modifier matches key-release events instead of the default key-presses.

Generally keys have the same names as their X keysyms, there are several specially defined keys:

SPC, TAB, RET, ESC, BS, DEL, Up, Down, Left, Right.

Also, there are several pseudo-keys for describing mouse events:

Click1, Click2, Click3, Off, Move.

So, for example, a single click of the left mouse button with the Meta key held would be described as M-Button1-Click1, while pressing the RET key with Shift held would be described as S-RET.

Functions are available to convert between the name of an event and the actual event itself, and vice versa.

 -- Function: lookup-event event-name
     Create and return a new input event whose name is EVENT-NAME.

          (lookup-event "C-x")
              => (120 . 65540)

          (lookup-event "C-M-Button1-Click1")
              => (1 . 131340)

 -- Function: event-name event
     This function returns a string naming the input event EVENT.

          (event-name (lookup-event "C-x"))
              => "C-x"

The keysyms generating the two virtual modifiers may be identified through the following variables:

 -- Variable: meta-keysyms
     A list defining the names of the X keysyms generating the virtual M modifier.

 -- Variable: alt-keysyms
     A list defining the names of the X keysyms generating the virtual A modifier.

 -- Variable: hyper-keysyms
     A list defining the names of the X keysyms generating the virtual H modifier.

Commands
********

A command is a Lisp function which may be called interactively, that is, either as a result of being bound to an input event.

Commands are defined in the same way as functions (using defun), but the body forms of the command must contain an interactive declaration. This marks that the function may be called interactively and tells the call-command function how to compute the argument values to apply to the command.

The interactive declaration looks like a call to the special form interactive, in actual fact this special form always returns nil and has no side-effects. The only effect of this form is to show the call-command function that the function definition may be called interactively. The second element of the declaration form (after the interactive symbol) defines how the argument values applied to the command are computed.

The structure of an interactive declaration, then, is:

     (interactive [CALLING-SPEC])

When a command is defined this is how it includes the interactive declaration:

     (defun some-command (arg1)
       "Optional documentation string."
       (interactive ...)
       ...

The CALLING-SPEC form defines the argument values applied to the command when it is called interactively, it may be one of,

  * nil or undefined (i.e. (interactive)); no arguments are given to the command, this type of interactive declaration just shows that the function may be called interactively.

  * A string; zero or more lines (each separated by a newline character), each line defines how to compute one argument value. The first one or two characters of each line is a prefix defining exactly how to compute the argument, the rest of the line is an optional argument which some prefixes may use.

     The currently available prefixes are,

     e
          The event which caused this command to be invoked.

     E
          The event which caused this command, cooked into a string.

     p
          The prefix argument as a number, this will be 1 if no prefix argument has been entered.

     P
          The raw prefix argument.

     t
          The symbol t.

     %f
          The window which currently has the input focus, or nil if no window is focused.

     %w
          The result of calling the current-event-window function.

     %W
          The result of calling the current-event-window function, or if this returns nil or root, the currently focused window.

     A null line produces an argument value of nil.

  * Anything else; the form is evaluated and expected to return a list of arguments to apply to the command.

When a command is to be invoked, the call-command function is used. This builds a list of argument values to apply to the command (using its interactive declaration) then calls the command.

 -- Function: commandp OBJECT
     This function returns t if its argument may be called interactively. If OBJECT is a function (i.e. a symbol or a lambda-expression) it is a command if it contains an interactive declaration

     The only other object which is a command is a function call form; the use of these types of commands is discouraged but they can be useful sometimes.

 -- Function: call-command command &optional prefix-arg
     This function calls the command COMMAND interactively. See the documentation of commandp above for what constitutes a command.

     If the PREFIX-ARGUMENT is non-nil it defines the value of the current-prefix-arg variable for this command, normally the value of this variable would be taken from the global prefix-arg variable.

Keymaps
*******

Keymaps are used to associate events with commands. When an event occurs, the associated command is found and evaluated. A keymap is simply a list whose first element is the symbol keymap.

 -- Function: keymapp arg
     Returns t if ARG may be used as a keymap.

 -- Function: make-keymap
     Returns a newly-created empty keymap.

 -- Function: bind-keys keymap &rest bindings
     Installs zero or more key bindings into the keymap KEYMAP, then returns KEYMAP.

     Each binding is defined by two elements in the list of BINDINGS, the first defines the name of the input event (or the event itself) and the second defines the command to be associated with the event.

     For example to bind two keys in the keymap KEYMAP; the event C-f to the command foo and the event C-b to the command bar the following form would be used,

          (bind-keys KEYMAP
           "C-f" 'foo
           "C-b" 'bar)

 -- Function: unbind-keys KEYMAP &rest KEYS
     Removes the bindings of the events KEYS (these may be the names of the events or the event objects themselves) from the keymap KEYMAP.

 -- Function: search-keymap event keymap
     Search for a binding of the event EVENT in KEYMAP. If a binding is found a cons cell (COMMAND . EVENT) is returned.

There are several pre-defined keymaps that are always available:

global-keymap
     Keymap containing bindings active anywhere.

window-keymap
     Keymap containing bindings active when a client window is focused.

root-window-keymap
     Keymap containing bindings active when the pointer is in the root window.

title-keymap
border-keymap
     Keymaps active in the title and borders of window frames.

close-button-keymap
iconify-button-keymap
maximize-button-keymap
menu-button-keymap
     Keymaps active in the standard window frame buttons.

Event Loop
**********

The event loop reads all X events received on any of the windows that Sawfish is aware off. Many of these events invoke hooks, as described in Standard Hooks. Keyboard and pointer events are translated to their Lisp equivalents (see Events) and then used to scan all active keymaps for a binding. If a binding is found, the associated command is invoked through the call-command function.

The active keymaps are determined as follows:

  * If the variable override-keymap is non-nil, then this is the only keymap searched

  * Otherwise three keymaps are searched:

      1. the keymap property of the currently ``clicked'' frame part if there is one,

      2. the keymap property of the currently focused window

      3. the contents of the variable global-keymap.

Note that for ButtonRelease events, the frame part's keymap is only searched if the pointer is actually within the frame part when the release event occurs.

If no binding may be found in any of the active keymaps, then the unbound-key-hook hook is called. This is an or type hook---the first function that returns non-nil will terminate the hook call.

 -- Function: lookup-event-binding event
     Perform the usual binding lookup for the event object OBJECT. Returns the command found, or nil if no binding exists.

By default, both key-release events, and events that are bound to modifier keys (e.g. Control_L), are ignored. However, this behavior may be changed:

 -- Variable: eval-modifier-events
     When non-nil, key events bound to modifier keys are evaluated.

 -- Variable: eval-key-release-events
     When non-nil, key-release events are evaluated.

While a command is being evaluated, information about the event that caused it may be found:

 -- Function: current-event
     Return the event which caused the current command to be invoked

 -- Function: current-event-string
     Returns the string which the current event would usually insert.

 -- Function: current-event-window
     Return the window that received the current event, or the symbol root, or nil if no such window.

 -- Function: last-event
     Return the previous event which occurred.

 -- Function: proxy-current-event window &optional mask propagate
     Send the current X event to WINDOW, either a window object, a numeric window id, or the symbol root. If a ButtonPress event the pointer grab will be released first.

     MASK may be an integer defining the X event mask to pass to the XSendEvent function. If not defined, a mask is chosen that would usually be used to select the type of event being proxied.

 -- Function: allow-events mode
     This is a wrapper for the XAllowEvents function. The MODE parameter may be one of the following symbols: async-pointer, async-keyboard, sync-pointer, sync-keyboard, replay-pointer, replay-keyboard, async-both, sync-both.

     Events that have to be grabbed to be received (i.e. all bindings in the global-keymap and the window-keymap) are grabbed synchronously. This means that no more events will be received until either the command returns, or allow-events is called.

     This is normally not important, but if the command expects to receive further events it must call allow-events. See the interactive move and resize functions for an example.

 -- Function: forget-button-press
     Cause the next button press to be treated as a single click event, no matter how soon it occurs after the prevous button-press event.

 -- Function: accept-x-input &optional mask
     Handle any X events received. If MASK is non-nil then only events matching this numeric value are handled (see the X header files for details).

 -- Function: x-events-queued
     Returns the number of X events waiting to be handled.

Miscellaneous Functions
***********************

Pointer Functions
=================

 -- Function: query-pointer &optional from-server
     Returns a cons cell (X . Y) representing the current mouse pointer position, relative to the origin of the root window.

     If FROM-SERVER is non-nil then the position is read directly from the server, otherwise it's taken from the current event (if possible).

 -- Function: query-pointer-window
     Returns the top-level window under the mouse pointer, or nil if the cursor is in the root window.

 -- Function: query-last-pointer
     Returns a cons cell (X . Y) representing the second most recent mouse pointer position, relative to the root window.

 -- Function: warp-cursor x y
     Move the mouse pointer to position (X, Y) relative to the origin of the root window.

 -- Function: warp-cursor-to-window window &optional x y
     Move the mouse pointer to position (X, Y) relative to the client window associated with object WINDOW.

     If X and Y are nil, then they are taken as the top-left corner of the window's frame.

Grab Functions
==============

 -- Function: grab-server
     Prevent any other clients from accessing the X server.

 -- Function: ungrab-server
     After a call to grab-server this will allow other clients to access the X server again.

     Note that calls to grab-server and ungrab-server nest.

 -- Macro: with-server-grabbed &rest forms
     Evaluate forms with the server grabbed. Releases the grab afterwards.

 -- Function: server-grabbed-p
     Returns t if the X server is currently grabbed.

 -- Function: grab-pointer &optional window cursor
     Grab the mouse pointer and direct all pointer events to window object WINDOW. If CURSOR is defined and a cursor object, display this while the pointer is grabbed.

     If WINDOW is nil, or unviewable, the grab will be made on the root window.

     Returns y if the grab succeeded.

 -- Function: ungrab-pointer
     Release the grab on the mouse pointer.

 -- Function: grab-keyboard &optional window
     Grab the keyboard and direct all keyboard events to window object WINDOW. If WINDOW is nil, or unviewable, the grab will be made on the root window.

     Returns non-nil if the grab succeeded.

 -- Function: ungrab-keyboard
     Release the grab on the keyboard.

Display Functions
=================

 -- Function: screen-width
     Return the width of the root window.

 -- Function: screen-height
     Return the height of the root window.

 -- Function: draw-window-outline mode x y width height
     Draw an outline of a window of dimensions (WIDTH, HEIGHT) at position (X, Y) relative to the root window.

     MODE is a symbol defining the type of outline drawn, currently it may only be box for a 3x3 grid.

     Use the erase-window-outline to erase the grid. Also note that since these functions draw directly on the root window the server should be grabbed until the outline is erased.

 -- Function: erase-window-outline mode x y width height
     Erase a previously drawn outline of a window of dimensions (WIDTH, HEIGHT) at position (X, Y) relative to the root window.

     MODE is a symbol defining the type of outline drawn, currently it may only be box for a 3x3 grid.

 -- Function: display-message &optional text attributes
     Display the string TEXT in a window on the screen. If TEXT is nil then any string previously displayed is removed. Returns the numeric id of the window displaying the message, or nil if no message is displayed.

     ATTRIBUTES is an alist specifying how the string should be displayed; each element of the list is a cons cell (ATTR . VALUE) associating an attribute ATTR (a symbol) with it's value.

     Possible attributes currently include:

     font
          The font to use

     foreground
          The color (or color name) to draw the text with

     background
          The color (or color name) to draw the background with

     x-justify
          The justification method for multi-line strings. One of the symbols left, right, or center

     spacing
          The number of extra pixels of vertical spacing to leave between text lines.

     position
          A cons cell defining the coordinates at which to display the message window. The cell is (X . Y). X and Y are integers or nil (for centered display). If negative they count in from the left and bottom edges respectively.

     head
          The head on which to center the message when a position is not specified or given as nil.  If not provided defaults to the head containing the window that has the input focus.

Gradient Functions
==================

The gradient feature allows color gradients to be drawn in images. (Evaluate (require 'gradient) to load this feature.)

 -- Function: draw-vertical-gradient image from to
     Draw a vertical color gradient in IMAGE. The color at the top of the image will be FROM, the color at the bottom TO, with a smooth transition between.

 -- Function: draw-horizontal-gradient image from to
     Draw a horizontal color gradient in IMAGE, from left to right.

 -- Function: draw-diagonal-gradient image from to
     Draw a horizontal color gradient in IMAGE, from the top-left corner to the bottom-right.

Other Functions
===============

 -- Function: sync-server
     Flush all pending X requests, don't wait for them to finish.

 -- Function: send-client-message window type data format
     Send an X ClientMessage event to WINDOW (a window object, the symbol root or a numeric xid).

     The event will be of the type TYPE (a symbol), contain the array of integers DATA (i.e. a vector or a string), and will be transferred as FORMAT sized quantities (8, 16 or 32).

 -- Function: create-window parent x y width height
     Create an unmapped window that is a child of PARENT (a window object, an integer window id, or the symbol root), with the specified dimensions.

     Returns the window id of the new window.

 -- Function: x-atom symbol
     Return the integer identifying the X atom with the same name as SYMBOL.

 -- Function: x-atom-name integer
     Return the symbol with the same name as the X atom identified by the integer INTEGER.

Standard Hooks
**************

Sawfish provides many hooks to allow extension of previously defined functions. Also, many X events are exported to the Lisp environment via the hooks mechanism. For more details on the hooks mechanism see Normal Hooks (The Librep Manual).

As well as using the standard call-hook function, sawfish also provides the call-window-hook function. This is used to invoke hooks which refer to a single window. If the hook has a local value defined in the window's property list then this value is used, before the default value defined by the actual variable.

 -- Function: call-window-hook hook window &optional args hook-type
     Call HOOK for WINDOW with further arguments ARGS. See call-hook for a description of HOOK-TYPE. Each function in the hook is called with arguments (WINDOW . ARGS).

The following table describes all standard hooks called by Sawfish, and the arguments they are called with:

pre-command-hook
     Called before each command is evaluated.

post-command-hook
     Called after each command is evaluated.

unbound-key-hook
     Called when an key or pointer event has been received which there is no binding for.

before-add-window-hook
add-window-hook
     Called with a single window when the window is first adopted by the window manager. before-add-window-hook is called first, it should only set properties of the window.

destroy-notify-hook
     Called when the window is destroyed. Note that this may be called asynchronously to the normal event loop. In general, the window manager will attempt to call this hook as soon after it knows the window has been destroyed as is possible.

map-notify-hook
unmap-notify-hook
reparent-notify-hook
enter-notify-hook
leave-notify-hook
focus-in-hook
focus-out-hook
shape-notify-hook
     Called with a single window argument, analogous to the X events of the same names.

configure-request-hook
     Called with two arguments (WINDOW ALIST) when an X ConfigureRequest event is received. ALIST may include items (stack . above), (stack . below), (position . COORDINATES), (dimensions . DIMENSIONS).

enter-frame-part-hook
leave-frame-part-hook
     Called with two arguments, the window and the frame part class (see Frame Part Classes), when the pointer enters or leaves a frame part.

window-moved-hook
window-resized-hook
     Called with a single window argument whenever the window is moved or resized.

visibility-notify-hook
     Called with two arguments, the window, and a symbol, one of: fully-obscured, partially-obscured, unobscured.

property-notify-hook
     Called with arguments (WINDOW ATOM-NAME TYPE) where TYPE is new-value or deleted.

client-message-hook
     An or type hook. Called with arguments (WINDOW TYPE DATA-ARRAY).

enter-workspace-hook
leave-workspace-hook
workspace-state-change-hook
     Called with a single argument: the workspace.

add-to-workspace-hook
remove-from-workspace-hook
     Called with a single argument: the window.

viewport-resized-hook
     Called when the number of rows and columns in each virtual workspace is changed.

viewport-moved-hook
     Called when the origin of the viewport into the virtual workspace is moved.

place-window-hook
     An or type hook. Called the first a window is mapped.

window-state-change-hook
iconify-window-hook
uniconify-window-hook
shade-window-hook
unshade-window-hook
window-maximized-hook
window-unmaximized-hook
window-depth-change-hook
     Called with a single window.

after-initialization-hook
     Called after adopting the initial set of windows.

before-exit-hook
     Called immediately before exiting.

sm-window-save-functions
sm-restore-window-hook
sm-after-restore-hook
     Session management hooks, Session Management.

before-move-hook
before-resize-hook
     Called before starting an interactive move or resize, with a single argument: the window.

while-moving-hook
while-resizing-hook
     Called while interactively moving or resizing the window passed as the argument to the hook.

after-move-hook
after-resize-hook
     Called after completion of an interactive move or resize. Called with two arguments: the window, and a list of symbols defining how the window was moved or resized.

gtkrc-changed-hook
     When using the gtkrc module to load the current gtk style parameters, this hook is called when the style changes.

enter-flipper-hook
leave-flipper-hook
     When viewport edge-flipping is enabled, these hooks are called as the pointer enters and leaves the pixel-wide border on the edge of the screen. They're called with a single argument, one of the symbols left, right, top, bottom defining the edge in question.

Standard Window Properties
**************************

As described in an earlier section of this manual, each window has a property list, which may be used to associate arbitrary lisp data with symbolic keys (see Window Property Lists). The following table documents a subset of the keys currently used.

ignored
     When set, the window is ignored in many operations.

avoid
     When set, the window will not be covered when maximizing, or when placing using the first-fit or best-fit methods

workspaces
     A list of integers defining the workspaces that the window is a member of, or nil if the window is sticky. See Workspaces.

sticky
     Whether the window should appear on all workspaces.

sticky-viewport
     When set, the window will appear in all viewports of its workspace.

keymap
     An optional, window-local, keymap. See Keymaps.

focus-click-through
     When set, and click-to-focus mode is enabled, the click that focuses a window is passed through to the client window.

ignore-window-input-hint
     When set the value of the window's input hint is ignored, i.e. the focus will be given to the window when appropriate

never-focus
     When set the window will never be given the input focus

focus-when-mapped
     Focus the window when it is mapped on to the display.

ignore-program-position
     When set the window's program-position property is ignored, use this with windows that set this hint incorrectly.

place-mode
     When set, the placement mode to be used with this window.

placement-weight
     When set, the weight assigned to the pixels in this window when doing fitted window placement.

type
     The frame-type of the window, or nil. See Frame Types.

frame-style
     The frame style explicitly chosen by the user, or unset. See Frame Styles.

current-frame-style
     The frame style currently used for the window. See Frame Styles.

removed-classes
     A list of frame part classes removed from the decorations of this window. See Removing Frame Parts.

shaded
     Is the window shaded? See Shading Windows.

hide-client
     Is the client window visible within its frame. Used to implement window shading.

depth
     An integer, the layer that the window is a member of. Layer zero is the depth of ``normal'' windows, negative depths are below this level, while positive depths are above. See Window Stacking.

placed
     Has the window been placed in a position yet? The place-window-hook is only called when this is unset.

iconified
     Is the window iconified? See Iconifying Windows.

gravity
     When set, overrides the window gravity field of the window's size hints. May be one of the symbols: north-west, north, north-east, west, center, east, south-west, south, south-east.

fixed-position
     When set, the user is not allowed to change the position of this window.

client-set-position
     When set, the program owning the window has manually moved the window after it was mapped.

Session Management
******************

Sawfish has fully integrated support for the X session management protocols. Also, this support is extensible to allow all Lisp modules to save and reload their own window state.

There are two methods of doing this. If the module only wants to save and restore the values of properties in each window's property list (i.e. those values set via window-put), then the following function may be used:

 -- Function: sm-add-saved-properties &rest properties
     Arrange for all symbols PROPERTIES to be saved and loaded with the session.

If a Lisp module chooses to use this method it may add a function to the add-window-hook to act on the reloaded properties when the session is reloaded.

For more complex window properties that can't be saved straight from the window's plist two hooks are available:

 -- Variable: sm-window-save-functions
     A list of functions, each of which is called when the state of each window is saved. Each function is called with a single argument (the window) and should return a list of alist elements that will be saved in the state file. (As such, only values with valid read syntaxes may be included.)

 -- Variable: sm-restore-window-hook
     List of functions called when the state of a window is restored. Each is called with arguments (WINDOW ALIST), where ALIST defines the state saved for the window.

     Each function should look for the properties it saved, and then take any action dependent on the values.

The following hook is also called.

 -- Variable: sm-after-restore-hook
     Hook called after loading a saved session.

     [file faq.texi not included]