   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 Copying (emacs)).

     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 (librep)),
this is a run-time library implementing a language
similar to Emacs Lisp (see Overview (elisp)), but with many
extensions, and using lexical instead of dynamic scope. This manual
assumes at least a basic knowledge of the language.

News
****

This lists the user-visible changes made to Sawfish, and which releases
they occurred between. For more detailed information see the
`ChangeLog' files in the Sawfish source tree.

1.3
===

   * Implemented EMWH "show desktop" mode

   * Set client window gravity to `StaticGravity' while reparenting
     windows (Michal Maru¹ka)

   * Support EWMH `SKIP_TASKBAR' state (Chris Boyle, me)

   * Window history keys may have multiple properties (not enabled by
     default for backwards compatibility, see `window-history-key'
     variable)

   * More placement modes are now multihead-aware (Steve Hill)

   * Translation updates: el (Simos Xenitellis, Kostas Papadimas), de
     (Christian Neumair), no (Kjartan Maraas), pt_BR (Alexandre Folle de
     Menezes), am (Daniel Yacob), es (German Poo Caaman~o), uk (Maxim
     Dzumanenko), sk (Stanislav Visnovsky)

   * Bug fixes:

        - compile with Gtk 2.2

        - don't try to unfocus windows within the X error handler

        - don't cache frame objects while clicking in windows, they may
          get garbage collected - fixes "crash on shading" bug

        - set `_NET_WM_NAME' as `UTF8_STRING' type (Christian Krause)

        - `save-session' is now called `gnome-session-save'; fallback
          to looking in `/usr/gnome' for menus

        - fixed typo in `adjust-position-for-gravity/y'

1.2
===

   * Added an `OPTIONS' file describing the variables that may be
     customized

   * Some drawing optimizations: don't reinstall frame shape at each
     redraw, turn off graphics exposures in all contexts

   * Added a cache for X properties to minimize server round-trips

   * Added support for Xft fonts

   * Color objects now store alpha as well as rgb data

   * Support useful parts of 1.1 NET WM spec; also fixed some bugs /
     omissions in support for 1.0 spec (e.g. `_NET_WORKAREA')

   * Support for two dimensional workspace layouts and edge flipping
     (Michael Toomin)

   * Translation updates (Dmitry G. Mastrukov, Jordi Mallach, Vincent
     van Adrighem, Christian Rose, Stanislav Visnovsky, Daniel Yacob,
     Andras Timar, Sava Chankov, Christian Neumair, Peteris Krisjanis,
     Gustavo Noronha Silva, Christian Meyer, Fatih Demir, Hasbullah Bin
     Pit, Christophe Fergeau)

   * Bug fixes:

        - Don't pass null pointers to `accept ()'

        - Stacking list assertions no longer abort execution, they just
          print an error message

        - Handle minimum-size hints that are zero

        - Understand the Pango font names that the Gtk2 font selector
          uses

        - Fixed bugs when iconifying sticky windows

        - When servicing configure-window requests, respect the window's
          locked dimensions. Also handle moving in only one direction

        - `grow-pack' bug fixes (Daniel Pfeiffer)

        - Fixed some problems with fullscreen mode

        - Fixed some problems in the Gtk2 config tool

        - Other bug fixes (Greg Morris, Claudio Bley)

1.1
===

   * Reorganized the customization options. Removed user levels.
     Removed many obscure options (most are still available as lisp
     variables, just not from the UI). Viewports are no longer
     available in the UI

   * Updates to the `grow-pack' module (Kai Großjohann, Daniel Pfeiffer)

   * In matched windows, boolean options can be turned off as well as
     on (me, merlin)

   * New full screen maximization mode

   * Bug fixes:

        - Miscellaneous focus fixes

        - Be more selective about which X errors imply window deletion

        - Don't trigger a stacking-list assertion on logout

        - Check for window-ness in window-visibility (Michal Maru¹ka)

        - Reread WM_WINDOW_PROTOCOLS when it changes

        - Fixed bug of nautilus windows not being focused in focus
          follows mouse modes

        - Recover "lost" windows when selecting windows (merlin)

        - Show correct size when resizing windows (merlin)

        - Most placement modes now respect workarea (Federico Mena
          Quintero, me)

        - Miscellaneous fixes to wm-spec implementation. Includes code
          to support _NET_WM_STRUT

        - Call `bindtextdomaincodeset' function if rep implements it
          (Christophe Fergeau)

        - Make the current-directory stored in the session a valid
          filename

        - Don't put windows below the default depth just because their
          parent is

        - Miscellaneous viewport fixes (Federico Mena Quintero)

        - Don't let "transients above" and "layer" stacking constraints
          conflict with one another

1.0.1
=====

   * Translation updates: pt (Carlos Perelló Marín), it (Michele
     Campeotto), pl (Zbigniew Chyla), zh_CN (Wang Jian), zh_TW (Abel
     Cheung), es (Eneko Lacunza), tr (Ömer Fadýl USTA), sv (Göran
     Uddeborg, Christian Rose), da (Ole Laursen), gl (Jesus Bravo
     Alvarez)

   * Bug fixes:

        - Fixed typo in `apply-command-keys' function (David Bustos)

        - Fixed bug in `wm-spec' module causing nautilus desktop window
          to cover panel

        - Adopt windows with a maximized hint correctly

        - Fixed bug in `display-window' function that can prevent the
          window getting focused

        - Don't allow windows to be moved or resized by third-parties
          when they're maximized (and the necessary option is set)

        - Fixed problem with localizing property names in the
          matched-windows configuration widget

        - Handle window gravity more correctly (Owen Taylor)

        - Forget everything about withdrawn windows - better ICCCM
          compliance

        - Fixed root-window event proxying (the infamous gmc bug)

        - Don't use dlmalloc on sparcs (Brian Nitz)

0.99
====

   * Requires `librep' 0.14 or newer

   * Translation updates: ja (Sato Satoru), no (Kjartan Maraas), es
     (Carlos Perelló Marín), fi (Antti Ahvensalmi), cs (Jiri Cerny), fr
     (Christian Marillat), de (Matthias Warkus, Christian Meyer), da
     (Ole Laursen), sk (Stanislav Visnovsky), tr (Özgür), sv (Christian
     Rose, Peter Winnberg), gl (Jesus Bravo Alvarez)

   * Do i18n on more text strings (Vlad Harchev, me)

   * Broken support for multiple-screen displays. Supplying the new
     `--multihead' option will fork extra copies of sawfish for each
     extra screen. This has some fundamental problems, but some people
     seem to want it (Michael Vogt, Mahmood Ali, me)

   * Window manager virtual modifier once again defaults to `M-'
     instead of `C-'

   * Added support for `Off2' and `Off3' events

   * `menu-program-stays-running' variable now defaults to true by
     popular demand

   * New command `focus-desktop'

   * Switch viewports more efficiently (by choosing the best order to
     move windows, to minimize the exposed area)

   * Monitor the `_WIN_WORKSPACE' property of each window

   * Bug fixes:

        - Check for X SHAPE extension, exit if it's not available

        - Wait for the focus-in event before changing sawfish's
          knowledge of the focused window when moving focus from one
          window to another

        - Be more ICCCM-compliant, don't send synthetic configure notify
          events when the window was resized

        - Fixed locale font handling

        - Don't leave grid traces when trying to move/resize a window
          that's locked in place

        - Fixed bug where the pointer being over the message window
          could confuse focus after window cycling

        - `decorate-transients' option works again with shaded windows

        - Documentation appears in tooltips again

        - Handle sticky properties better in the `window-history' module

        - Maximization fixes for multi-headed displays (Florent
          Guillaume)

        - Cancelling a resize of a maximized window no longer discards
          the window's maximized state

0.38
====

   * Translation updates: gl (Jesus Bravo Alvarez), sv (Martin
     Norbäck), de (Matthias Warkus, Christian Meyer), ru (Vlad
     Harchev), es (Joseba García Etxebarria), pl (Daniel Koc), fi
     (Antti Ahvensalmi), sk (Stanislav Visnovsky), az (Pablo
     Saratxaga), cz (Stanislav Brabec), no (Kjartan Maraas), el (Simos
     Xenitellis), it (Michele Campeotto), fr (Christian Marillat), ro
     (Marius Andreiana), ko (?)

     Extract some more translatable strings (Vlad Harchev)

   * `Crux' theme now has an extra button mode: `Default', like Mac OS
     Platinum but also has an iconify button. Used by default

   * The `grow-pack' module now works with windows which specify
     increments (Kai Großjohann)

   * New command `kill-client'

   * Fixed bugs:

        - Don't return a null pointer when no default cursor has been
          set, return `nil' instead

        - Avoid triggering assertions in the stacking list code when
          raising or lowering windows and the given sibling has been
          destroyed

        - Turned off the annoying code that beeps and prints a message
          when unfocusable windows are detected

        - The GNOME hints now listen for the `_WIN_WORKSPACE' property
          changing and will move the window in response

        - Don't forget maximized state of windows when they're moved,
          only if they're resized

        - Don't show special cursors when moving or resizing windows, or
          when hovering over the title bar

        - Corrected off-by-one error in `smart' placement modes

        - Identified and fixed some problems in the new GNOME/KDE window
          manager hints implementation (Rob Hodges, me)

0.37
====

   * New command line option `--window-history-file=FILE'

   * Search for user's rc file in this order: `~/.sawfishrc',
     `~/.sawfish/rc', `~/.sawmillrc'

   * New option `configure-ignore-stacking-requests' and a
     similarly-named window property. When set stacking requests from
     windows are ignored (Matt Tucker)

   * When restarting sawfish, reselect the previously selected workspace

   * Added a function that can recolour multiple image channels
     simultaneously

   * New function `exit-type' - returns the type of exit in progress

   * Translation updates: ja (Sato Satoru), sk (Stanislav Visnovsky),
     es (Iñaki García Etxebarria), hu (Robert Vanyi), tr (Fatih Demir),
     ro (Tutu Valentin), no (Kjartan Maraas), it (Michele Campeotto), pl
     (Daniel Koc)

   * Fixed bugs:

        - Fixed focus-handling in enter-only mode on window close and
          viewport switch

        - Fixed overflow error in the image recolouring module (Simon
          Budig)

        - Session management always uses a unique session file (Timo
          Korvola, me)

        - Fixed bug in random placement mode where windows could
          sometimes be placed off-screen

        - Fixed some auto-raise problems by reverting a misguided bug
          fix

        - Fixed bugs with aborted session saves

        - Cache stacking order of windows locally - this allows us to
          keep the order consistent, especially after window
          reparenting operations

        - Don't call `XParseColor' unless we actually _have_ a display
          connection (merlin)

        - Merged two calls to `setlocale' to avoid trashing the locale
          preferences

        - Check for presence of Xinerama extension before trying to use
          it - removes the annoying error message at startup

        - Added some more X server timestamp logic to correct for the
          timestamp discontinuities after APM resume

0.36
====

   * Added a new default theme: `Crux'. By default it recolours itself
     to match the current GTK+ selection colour. (Arlo Rose, me)

   * Updated translations: it (Michele Campeotto), fr (Christian
     Marillat)

   * Added a `shade-button' button class (many themes created it anyway)

   * Added a `sawfish.wm.util.recolor-image' module, currently contains
     a single function for recolouring parts of images based on a given
     colour gradient

   * Added new command `delete-group'. Deletes a whole group of
     windows. With default bindings, shift-click on the close button to
     invoke this command

   * Added support for KDE-style mini-icons. If the window has no
     normal icon, then `window-icon-image' will return the mini-icon

   * Fixed bugs:

        - Themes that use the module for reading the user's gtk
          preferences will once again get updated when the gtk theme
          changes

        - Fix another of the null-string translation bugs (Christian
          Marillat)

        - Work around `XUrgencyHint' not being defined before X11R6

        - Fixed some long-standing bugs when decorating windows (use the
          correct mask when creating the overall window shape; for
          frame parts with no mask, set the local shape to the
          appropriate rectangle; be sure to generate at least one
          Expose event when reconfiguring frame parts)

        - Fixed crashing bug when `bind-keys' is called with zero
          arguments

        - Fixed typo in `crop-image' function when checking validity of
          HEIGHT parameter (martin@whoever.com)

0.35
====

   * Translation updates: ja (SATO Satoru), it (Michele Campeotto),
     zh_TW.Big5 (Chun-Chung Chen), pl (Daniel Koc), sk (Stanislav
     Visnovsky)

   * Items in `choice' widgets may now contain descriptive names,
     syntax is `(SYMBOL "DESCRIPTION")'

   * Changed `focus-windows-when-mapped' option to only apply to
     non-transient windows (this option is now enabled by default)

   * New placement modes `top-left' and `off-center'.  `top-left' is
     now the default mode for non-transients

   * Enabled the module supporting the newly standardized GNOME/KDE
     window manager hints. Also made random changes to support KDE2 a
     lot better

   * Added WM_PROTOCOLS `_SAWFISH_WM_RAISE_WINDOW' and
     `_SAWFISH_WM_LOWER_WINDOW'. Used by `maybe-raise-window' and
     `maybe-lower-window' functions.

     These are similar to `WM_TAKE_FOCUS', in that if the window
     supports the protocol, it's up to it whether or not it raises (or
     lowers) the window in question. These functions should only be used
     where the user hasn't explicitly requested the restacking

     An example usage is an application that doesn't want its window to
     be raised due to a button-press event that initiates a drag
     operation

   * New option `menus-include-shortcuts', disabled by default (Unai
     Uribarri)

   * Don't interpret windows with `WM_TRANSIENT_FOR' set to the root
     window as children of all windows in the group (it causes too many
     annoying effects), instead just decorate these windows as
     transients

   * Handle `group' and `transient' iconification modes better, don't
     use a recursive method, instead use one pass to identify the
     windows to change, then another to make the changes. In
     `transients' mode, only change the state of shared transients if
     they will have no visible parents afterwards

   * In the (old) GNOME hints code, support a `_WIN_HINTS' client
     message (with a similar format to the `_WIN_STATE' message)

   * New module `sawfish.wm.commands.viewport-extras', some commands
     for viewport for viewport navigation (Dams Nadé)

   * Check for `never-iconify' and `never-maximize' window properties
     when appropriate

   * Support sixth and seventh mouse buttons (Steve Haslam)

   * Bug fixes:

        - Fixed problems with reverting changes to list-based options

        - Don't allow the empty list as a valid modifier list

        - Fixed bug where restarting the wm with
          `focus-windows-when-mapped' set would cause any shaded
          windows to be deleted

        - Ignore iconified windows in the grow-pack code

        - Added `font-ascent' and `font-descent' functions to the gaol

        - Catch errors when loading site-init and rep-defaults files

        - Don't use `""' to denote a null doc string (which has bad
          side effects when internationalized)

        - Don't need to run `sawfish-client -' to get a repl anymore,
          just `sawfish-client'

        - Fixed bugs in `composite-images' function

        - Fixed ordering of states output by `gtk-style' program
          (michaelj@maine.rr.com)

        - Fixed grabbing mono window icons in gdk-pixbuf mode

        - Reject button event descriptions that don't specify at least
          one mouse button

        - Accept `()' as a valid image modifier color component

        - Now grabs translatable strings from `defgroup' forms correctly

0.34
====

   * Added a virtual modifier key, the `W-' modifier. This modifier is
     used for all standard window-manager key bindings, it may be set
     to any of the standard X modifiers using the configuration tool

   * Optionally show window-icons when cycling through windows (Unai
     Uribarri Rodríguez, me)

   * Event handlers for low-level X windows now get passed the window
     as their second argument (Unai Uribarri Rodríguez)

   * Translation updates: fr (Christian Marillat), sv (Richard Hult),
     pt_BR (Flávio Bruno Leitner), it (Michele Campeotto)

   * Error handler module (`sawfish.wm.ext.error-handler'). When loaded
     it records the most recent errors, and the time at which they
     occurred. Use the `display-errors' command to display all recorded
     errors.

   * Added an option to not save window-history data for transient
     windows. Also added a `window-history-clear' command to forget
     history for all windows.

   * Rearranged window operations menu to hopefully be clearer

   * Attempt to catch and handle errors while loading custom options

   * Labels in menu items can now be functions, they should return the
     label text when called (with any menu arguments)

   * Moved installed message catalogues to $datadir/locale

   * `defcustom' forms may now a `:widget-flags' keyword, a constant
     list of symbols passed to the configuration tool. Current flags
     include: `expand-vertically' and `expand-horizontally'

   * Added a `sawfish.wm.util.ping' module, it implements the
     `_NET_WM_PING' protocol of the new window manager spec.

   * `destroy-notify-hook' is no longer called asynchronously

   * Bug fixes:

        - Fixed various bugs when dragging/resizing windows

        - Reverted the changes to make the click-to-focus click-through
          setting apply to window decorations

        - Fixed bug when handling 32-bit data in client messages and X
          properties

        - Fixed window-focus problems when switching viewports

        - Many bug-fixes to handling of maximized window state.
          Maximized state should now be preserved across wm and session
          restarts. It's also saved in the window-history attributes

        - Support the function hints of the MWM window manager
          properties

        - Updated the `sawfish.wm.state.wm-spec' module to match the
          current (almost final) draft of the new GNOME/KDE window
          manager spec

        - Fixed sporadic stacking bugs when unmapped windows exist

        - Fixed miscellaneous click-to-focus and focus-click-through
          related bugs

0.33
====

   * Added support for user-levels associated with individual commands

   * The GNOME hints code now understands that the do-not-cover flag is
     the same as sawfish's `avoid' property

   * Swap properties of sticky windows when entering and leaving
     workspaces as for normal windows (fixes the old problem where
     sticky windows can grab focus when a workspace is entered)

   * Changed the default settings of some customization options,
     hopefully to give a more "conventional" feel for new users

   * Better support for Xinerama (Geoff Reedy)

   * Added a new set of window stacking commands: `raise-window',
     `lower-window', `raise-lower-window'. The set of windows affected
     by these commands is determined by the `user-raise-type' (either
     the individual window, the window and any transients, or the
     entire group). The old commands of these names are now called
     `FOO-single-window'.

     Most modules now use these commands when raising or lowering
     windows, allowing the stacking model to be configured globally.

   * Translation updates: no (Kjartan Maraas), fi (Antti Ahvensalmi),
     it (Christopher R. Gabriel), pt_BR (Douglas Moura Ferreira), uk
     (Yuri Syrota), de (Matthias Warkus)

   * Fixed bugs:

        - If committing changes in the configurator causes new
          customization options or groups to be added, update the UI to
          reflect this

        - Added code to detect and correct the sporadic bug where
          windows become unfocusable in click-to-focus mode

        - Sanitized how the focus gets passed to and from transient
          windows (when passing focus back from a transient, give it to
          the most recently focused window in the group, not the
          transient's parent)

          Also, try to avoid displaying maximize buttons in windows
          whose hints prevent them from being maximized

        - Many fixes to how maximized windows are handled across session
          and window manager restarts. Also support GNOME window
          maximized hints when windows are created

        - Fixed some bugs in the `wm-spec' module

        - Don't trigger auto-raise hooks on leave/enter events
          generated by pointer grabs

        - The `edge-flip-delay' option now applies when dragging windows

        - Fixed the preview command in `sawfish-themer'

        - Miscellaneous fixes to the "smart" window placement modes

        - Fixed type description of `persisitent-group-ids' option

        - In `enter-exit' focus mode, focus isn't removed due to
          enter/leave events due to pointer grabs (fixes the bug with
          Mozilla URL completion)

        - Fixed (again) the `focus-click-through' behaviour with
          respect to frame decorations

        - Re-added hack to make GMC icons unfocusable

        - Fixed interactive placement to check for window destruction
          (merlin)

        - Fixed bug with tiled images with shapes (the shape mask would
          always be applied an integer number of times, ignoring the
          size of the frame part it's associated with)

        - Fixed `window-wants-input-p' to check if the `InputHint' is
          set before reading the value

0.32
====

   * `M-TAB' window cycling now works in both directions, bind keys to
     `CYCLE-COMMAND-backwards', e.g.  `cycle-windows-backwards'
     (Merlin, me)

   * Added support for X `Urgency' hint: `window-urgent-p' and
     `window-state-change-hook' is called with `urgency' state when it
     changes

   * Some improvements to `shade-hover' mode (adapted from Eli Barzilay)

   * Functions that raise/lower groups of windows now generate the
     minimum number of expose events (Rob Hodges, me)

   * New window property `window-list-skip'. Unified with GNOME
     skip-winlist hint

   * Custom options may have tooltips, use `:tooltip' tag

   * Catch errors when applying custom changes and revert to previous
     state

   * Translation updates: uk (Yuri Syrota), pt_BR (Douglas Moura
     Ferreira), hu (Róbert Ványi), de (Christian Meyer), ja (SATO
     Satoru), da (Keld Jørn Simonsen), es (Iñaki García Etxebarria), fr
     (Christian Marillat)

   * Fixed bugs:

        - With click-to-focus in non-click-through mode, don't
          click-through into window decorations

        - `dimensions' property in window matching was called `size' by
          mistake

        - Export the various `sp-cost:' functions from the
          `sawfish.wm.placement.smart' module

        - Don't allow cycles in the transient-for relationship

        - Fixed some maximize bugs

        - GNOME skip-focus property no longer causes the window to be
          unfocusable, just uncyclable-to

        - Coerce auto-raise timeout to be at least one millisecond;
          support `disable-auto-raise' correctly

        - Window input hints defaults to true not false

        - Fixed typo when loading the defaults file (Ronald Wahl)

        - Fixed command spec of `move-window-FOO' commands (Yoshiki
          Hayashi)

        - When sending `WM_TAKE_FOCUS' message, only focus the window
          if its `Input' hint is set

0.31.1
======

   * Translation updates: da (Kenneth Christiansen), de (Christian
     Meyer), no (Kjartan Maraas), pt_BR (Rui Miguel Silva Seabra), sv
     (Johan Dahlin), uk (Yuri Syrota)

   * Bug fixes:

        - Fixed typos in `sawfish.wm.gnome.integration' and
          `sawfish-themer' (Christian Marillat)

        - Fixed bug when building on Tru64 (John H. Palmieri)

        - Remember to check return value when initializing Imlib

0.31
====

   * Requires librep version `0.13'

   * Organized all lisp code into a hierarchy of modules. Root points
     are `sawfish.wm' for window manager code, `sawfish.ui' for
     configurator and `sawfish.gtk' for GTK+ utilities

     Compatibility should have been preserved as far as possible,
     through the use of module aliases. The `user' module that
     unmodularized user code is loaded in should look very similar to
     the old environment.  However, code using private functions,
     probably will not work

     New features written as modules can either import modules
     individually, or just open `sawfish.wm' to get the core
     functionality

   * All command handling is now written in Lisp. It's fully compatible
     except for how commands are defined. Since there is no longer a
     unified namespace the mapping from names to command definitions is
     maintained separately.

     `define-command' and `autoload-command' add entries to this
     mapping. `define-command' takes a name and a function (and some
     other optional arguments). The old style of defining commands still
     works, but only in the user module

   * `sawfish-client' now provides the same repl as the normal `rep'
     program. E.g. this allows the module system to be easily inspected

     Also, the module of each loaded theme is available for inspection
     under `themes.THEME-NAME'. (With themes using top-level defines
     instead of a single `let*' block, this is useful for debugging)

   * `sawfish.client' module provides lisp functions for communicating
     with a running window manager. Also, the protocol has been
     modified to support proper communication of errors, which are then
     re-raised on the client-side. This should make debugging
     client-server code more obvious

   * `Action' parts of menu items may now be lisp objects that don't
     have a read syntax. (E.g. this allows closures to be used,
     avoiding the problems arising from modularization)

   * Support for checked and radio-group menu items. Also a new
     function `add-window-menu-toggle' to add items to the `Toggle'
     sub-menu of each window

   * Handle `ConfigureRequest' events in a way that is compliant with
     the ICCCM--honour the window's `win_gravity' setting (defaulting
     to `NorthWest' gravity), instead of assuming `Static' gravity

   * Support more GC attributes in the `sawfish.wm.util.x' plugin (Ryan
     Pavlik)

   * Support for handling arbitrary windows as extra "root" windows.
     Used, e.g., to support Nautilus' desktop window. Allows the focus
     modes to work correctly

     To support this, new window property `desktop' denoting a
     "desktop" window; new function `desktop-window-p' recognizing one
     of these things (or the symbol `root')

   * Added `pointer-motion-threshold' option. Pointer motion events are
     only generated when the pointer moves at this many pixes away from
     the position it had when the button was pressed

   * New functions: `scale-image', `composite-images', and `crop-image'.

   * New option `maximize-avoid-avoided' (Jonas Linde)

   * New functions exported by `sawfish.wm.ext.tooltips' module:
     `display-tooltip', `remove-tooltip'

   * New function exported from `sawfish.wm.viewports' module:
     `select-workspace-and-viewport'. Renamed some workspace functions:

     `ws-move-window' => `move-window-to-workspace', `ws-copy-window'
     => `copy-window-to-workspace', `ws-insert-workspace' =>
     `insert-workspace', `ws-move-workspace' => `move-workspace',
     `ws-remove-window' => `remove-workspace'.

   * Changed interface of `get-visible-window-edges' function to use
     proper keyword parameters, and added some new keywords

   * New commands `help:about' and `gnome-about'. Added a
     `sawfish-about' script to implement the first of these. Added
     associate menu items to the `Help' menu

   * New window property `cycle-skip', defines whether the window is
     included when cycling the focused window. (Dave Dribin, me)

   * Translation additions and updates: es (Iñaki García Etxebarria),
     tr (Fatih Demir), zh_CN.GB2312 (zw@zhaoway.com), fr (Christian
     Marillat), ja (SATO Satoru), de (Kai Lahmann), el (Simos
     Xenitellis), ga (Seán Ó Ceallaigh), ru (Valek Filippov), sl
     (Andraz Tori)

   * Bug fixes:

        - Don't let errors in `.sawfishrc' prevent customization
          settings being loaded

        - initialize event handler when creating X window proxies (Matt
          Tucker)

        - No longer able to `throw' out the top of the program by
          mistake

        - Fixed `find-head' function, to allow Xinerama support to work

        - When exiting, leave window configurations exactly as they were
          found (E. Jay Berkenbilt)

        - Fixed `synthesize-event' to scan the window tree for a child
          window accepting button events (E. Jay Berkenbilt)

        - Removed "yow! ..." debugging messages

        - `image-set' and related functions will add an alpha channel
          to the image when necessary (when using gdk-pixbuf)

        - Canonify `S-x' as `X' where possible

        - Catch and handle errors when matching properties in the
          `sawfish.wm.ext.match-window'

        - Escape underscores in menu items where they shouldn't
          introduce accelerators. (Added `quote-menu-item' function to
          help with this)

        - Fixed race-condition when exiting configurator embedded into
          the GNOME control center (Havoc Pennington, me)

        - Fixed bug in `set' method of the `icon' widget

        - Fixed shading behaviour of included themes (Daniel Lundell)

        - Compute the shape of the frame window each time the
          background of one of its parts changes

0.30.3
======

   * If a frame part has a non-nil `hidden' attribute, ignore it

   * When reframing windows, keep the absolute position of the client
     window constant

   * Support `FIXED_POSITION' GNOME hint (renamed old `fixed-position'
     property as `client-set-position'; `fixed-position' now means
     don't allow the window to be moved by the user)

   * `transients-above' option can now be set per-window

   * Translation updates: fr (Christian Marillat), en_GB (Robert
     Brady), de (Kai Lahmann), da (Keld Simonsen), ru (Valek Filippov),
     sl (Andraz Tori), no (Kjartan Maraas), gl (Jesus Bravo Alvarez), it
     (Michele Campeotto)

   * Fixed bugs when converting option values

   * Fixed `:require' keyword in `defcustom' always causing the module
     to be loaded, not just when the option is non-nil

   * Fixed bug when adding windows that are shaded

   * Fixed some minor bugs in the configurator

0.30.2
======

   * Window cycling now forwards terminating events to external
     applications as well as internal bindings (e.g. `M-TAB M-w' closes
     an activated Netscape window)

   * `quote-event' command now works with applications that ignore
     synthetic events (adapted from code by Timo Korvola)

   * Reorganized frame style and window type management. New function
     `define-frame-type-mapper' allows modules to affect the mapping
     from window type to frame type. E.g. the shading module uses this.
     (fixes the bug that changing the frame type of a shaded window
     didn't work)

   * Added function `variable-customized-p'; use this to avoid
     redefining user-modified options

   * Do type-directed deep conversion of values when converting to/from
     readable representations. This fixes the bug that options with
     `:type (optional color)' weren't being converted when passed
     between the wm and the configurator, leading to reader errors

     A side-effect of this is that updated custom files will not be
     compatible with previous versions of the wm (though old custom
     files will work with new versions)

   * Translation updates: no (Kjartan Maraas), de (Kai Lahmann), nl
     (Dennis Smit), sl (Andraz Tori)

   * Added primitives `map-windows' and `filter-windows'

   * Fixed bug of not retaining focus on startup when originally in
     PointerRoot mode and moving to click-to-focus mode (Brad Thompson)

   * Ensure that apps get sent a synthetic ConfigureNotify event after
     ConfigureRequest events are handled (fixes bug where menus in Java
     apps can appear at wrong position until window is moved)

   * When referencing known variables from subroutines, make sure that
     restricted environment doesn't prevent the variable being accessed
     (fixes bug where `default-bevel-percent' was being ignored)

   * When creating transient groups, don't compare null group ids
     (fixes xfmail related bugs)

   * Fixed `move-window-to-viewport' command to correct for 1...
     indexing

   * Fixed non-gnome workspace widget in configurator

0.30
====

   * New commands `activate-viewport-column', `activate-viewport-row'

   * New commands `raise-window-and-transients',
     `lower-window-and-transients' and
     `raise-lower-window-and-transients',
     `raise-transients-and-pass-through-click'.

     As the normal window stacking commands, but restacks the
     "transient-group" of the window. This includes the window itself
     and any transients it has, and any windows that it itself is a
     transient of.

     These commands are used in the default keymaps

   * Functions that deal with transient windows now understand the de
     facto standard of setting the `WM_TRANSIENT_FOR' property to the
     root window denotes that the window is a transient for the whole
     group

   * New image manipulation functions: `image-ref', `image-set',
     `image-fill', `image-map'. New color accessor function
     `color-rgb-8'. New function `root-window-id'

   * Improvements to `sawfish-ui': optionally use some GNOME widgets,
     more lisp widget types, some bug fixes

   * New command `command-sequence'. Allows individual bindings to
     invoke a sequence of commands

   * Options `iconify-group-mode' and `uniconify-group-mode' replace
     `iconify-whole-group' and `uniconify-whole-group'.  New commands
     `iconify-transient-group', and `uniconify-transient-group'

   * Added `:type*' key to `defcustom', like `:type', but value is left
     unquoted

   * Translation updates: pl (Daniel Koc), ru (Valek Filippov), uk
     (Yuri Syrota), es (Iñaki García Etxebarria)

   * Fixed handling of `WM_NORMAL_HINTS' (was using base-size instead
     of min-size in places)

   * Fixed further locale / FontSet bug (Tomohiro KUBOTA)

   * `window-history' module won't resize a window to a size that
     violates its size constraints

0.29
====

   * Rewrote the configuration user interface. Improvements include:

        - Key bindings may now include parameters. E.g. this finally
          allows shell commands to be bound to keys using the GUI (use
          the new `run-shell-command' command)

        - Nautilus-like user-levels to tailor the options shown to the
          expertise of the user

        - Options may have much richer type descriptions (including
          `match-window' options). Also, extra widget types and
          containers may be added as extra Lisp modules

        - By default the stand-alone configurator commits changes to the
          window manager as they are made, instead of waiting for the
          `Try' button to be pressed

        - Added dependences--options with dependences are only editable
          when the value of their dependence is non-`nil'

   * Rewrote window stacking code to be based on "stacking
     predicates"--functions that accept or reject a possible stacking
     configuration. This allows the "stack-transients-above-parents"
     option to work correctly, only keeping transient windows above
     their _own_ parent windows

   * The configure-event handler now understands and handles the full
     complexity of stacking requests (Brad Thompson)

   * New frame-part attribute: `scale-foreground'. The `cursor'
     attribute may now be a function

   * Made the `centered', `centered-on-parent' and `under-pointer'
     placement modes clamp the window into the current work area (i.e.
     without overlapping windows that shouldn't be covered).  Added a
     `stagger' placement mode

   * When grabbing window icons to images, preserve their shape masks

   * Moved `window-history' options to `placement' group.  Fixed some
     more bugs and sub-optimal default option values

   * Don't set cursors for button classes, use the default value

   * GNOME `SKIP_FOCUS' window hint sets `never-focus' property on
     window, as well as the `ignored' property

   * Translation updates: de (Karl Eichwalder), ru (Valek Filippov), da
     (Kenneth Christiansen)

   * Added mostly-complete support for using gdk-pixbuf instead of
     Imlib (requires an experimental Xlib version of the gdk-pixbuf
     library)

   * Various bug fixes and other minor changes...

0.28.1
======

   * New options `--visual=TYPE' and `--depth=DEPTH'. These tell the
     window manager to use a different visual than the default

   * Made the `window-history' module behave more sanely (don't save
     iconified or shaded state; include window name when generating
     keys for transient windows)

   * Made `beos-window-module' the standard window menu (require
     `old-window-menu' to get the original version). Also made this
     display the windows' class names

   * Updated translations: es (Iñaki García Etxebarria), tr (Fatih
     Demir)

0.28
====

   * New module `window-history'--automatically saves window attributes
     when they are explicitly set by the user, then copies these
     attributes to windows with the same `WM_CLASS' as they are
     created. This is loaded automatically if you have no `.sawfishrc'

   * New method of allowing themes to implement only some of the
     (currently) four frame types. The variable
     `frame-type-fallback-alist' maps each frame type to the type to
     try if the original type isn't available in the chosen frame style.

     Note that for this to work, themes must return `nil' when they
     don't support the requested frame type, until now, the convention
     had been to return the default frame definition, so most if not
     all themes will need changing. (This doesn't include themes
     created using the `make-theme' module.)

   * Made the metrics used by the `best-fit' placement mode
     user-controllable. Set the `sp-cost-components' variable to a list
     of cost functions and the weight to apply to that metric. E.g. by
     default it gives 50% importance to the distance from the placement
     to the focused window, and 25% each to the distance to the pointer
     and to the "future-unusefulness" of the area being covered

   * New module `beos-window-menu' to redefine the window menu to group
     items by the window group that they are a member of (in the
     absence of actual group information, it will heuristically build
     groups by matching window titles)

   * New option `edge-flip-warp-pointer', whether or not to warp the
     pointer after edge-flipping (Paul Warren)

   * New option `display-window:uniconify-to-current-workspace',
     controls whether windows uniconified by `display-window' should be
     moved to the current workspace (John N S Gill)

   * Changed method of selecting when to use multi-byte aware rendering
     functions (except when initializing the locale fails, or returns a
     7-bit locale); also, when creating a fontset fails, try to
     intelligently fall back to a similar group of fonts (Tomohiro
     Kubota)

   * The `x' library now supports creating and then drawing to pixmaps.
     The pixmaps can then be grabbed to images using the
     `make-image-from-x-drawable' function

   * Added a `Help' item to the root menu

   * Translation updates: fi (Antti Ahvensalmi), gl (Jesus Bravo
     Alvarez), de (Karl Eichwalder), nl (Jan Nieuwenhuizen), pl (Daniel
     Koc), tr (Fatih Demir)

   * Now supports the `Super' modifier

   * Fixed bug of sometimes ignoring pending X events

   * Fixed bug of calling focus change hooks too many times (only when
     our view of the focused window has actually changed)

   * Avoid problems when windows set weird size hints structures

   * Raise windows _after_ possibly moving them to a different layer,
     when they have been mapped

   * When the `cycle-windows' sequence is terminated by an unknown
     event, re-handle that event after exiting (so that e.g.  `M-TAB'
     can be followed by another `M-' qualified event without releasing
     Meta)

0.27.2
======

   * Translation updates: da (Kenneth Christiansen), de (Karl
     Eichwalder), es (Iñaki García Etxebarria), ja (SATO Satoru)

   * Attempt to destructure the language code when parsing GNOME
     desktop items (e.g. if `LANG=de_DE' look for both `de_DE' and `de'
     translations)

   * New focus handler events `enter-root' and `leave-root'

   * Removed `raise-groups-on-focus' option, it caused unstable window
     flickering in certain cases

   * Fixed bug When transferring focus after a window is unmapped
     (inverted choice of when to look under pointer, and when to look in
     focus history)

0.27
====

   * Changed the name from `sawmill' to `sawfish'; all user-visible
     binaries have been renamed appropriately, the old programs will
     still work for now...

   * Added support for accelerators in menu definitions (this requires
     a new rep-gtk package) (Richard Kilgore). Added accelerators to
     many of the standard menu items

   * Added some (untested) support for Xinerama: `current-head',
     `current-head-dimensions', `current-head-offset'. Some placement
     modes should handle multiple heads sensibly, as should window
     maximization and edge snapping.

   * Added icons for GNOME control center applets (all icons by Tigert,
     except for the saw-blade logo by Glyph Lefkowitz)

   * New functions `map-window-properties' (me), `window-icon-image'
     (Bruce Miller)

   * Changed behaviour of `raise-group' and `lower-group' to preserve
     the stacking of the group, then change the selected window.  Added
     new command `raise-lower-group'

   * New option `raise-groups-on-focus'

   * Updated translations: de (Hubert Nachbaur), es (Iñaki García
     Etxebarria), gl (Jesus Bravo Alvarez), ko (Man-Yong Lee), tr
     (Fatih Demir)

   * Try to handle errors more gracefully when creating window frames

   * Better handling of errors in the control center applet

   * Fixed the `below-client' frame-part attribute

   * Fixed the disappearing items in the match-windows dialog

   * Fixed the non-beautified entries in the keymaps dialog

   * Fixed interactive placement mode (Timo Korvola)

   * Invoke audio playing program asynchronously, may avoid deadlocks

   * Fixed `workspace-menu' to add the focus-marking asterisk (John N S
     Gill)

   * Fixed menu-obscuring bug after auto-raising windows

   * Ensure that `WM_STATE' property is set each time a window is
     mapped, not just the first time

   * Fixed bug when discarding grab in click-to-focus mode, even though
     successive events may be in the window's keymap

   * Only focus windows when they're mapped when they're visible

   * Fixed click-to-focus problems when unmapping transient windows

0.26
====

   * Added plugin `selection', adds functions `x-selection-active-p'
     and `x-get-selection' for retrieving X selections (Mark Probst)

   * New functions `prompt-for-window', `prompt-for-workspace' and
     `select-workspace-interactively' (Dave Pearson)

   * `window-anim' module enabling asynchronous animations after window
     events. Currently only two animation styles `wireframe' and
     `solid', and they only animate window iconification

   * `audio-events' module; maps window manager events to audio samples
     (played using esd by default, but can be configured to use any
     program)

   * When running programs in terminals from the GNOME apps menu, use
     the value of `xterm-program' to decide which terminal program to
     use (James Antill)

   * Translation updates: gl (Jesus Bravo Alvarez), pl (Daniel Koc)

   * New command `toggle-window-iconified' (Jens-Ulrik Petersen)

   * New option `raise-windows-when-unshaded'

   * Customization options for tooltip colors (Erik Assum)

   * Removed default binding to `A-x'

   * Added support for librep-with-module-system (cvs version)

   * Note that `ko' and `zh' languages need FontSets

   * When sticking a window not on the current viewport, move it to the
     current viewport (Merlin)

   * Fixed bug (?) of placing over avoided windows in `random' mode;
     also increased `sp-avoided-windows-weight' by an order of
     magnitude (Dan Winship)

   * Fixed bug of maximizing a window changing its viewport

   * Fixed window cycling losing grab if originally focused window is
     unmapped

   * Fixed `get-cursor' to use the correct background color when
     creating cursors from vectors (Alexander Barinov)

   * Fixed `get-font' to set `descent' property correctly

   * Changed double-buffering semantics in `x' plugin, also only
     support this if configure finds the correct header files

   * Fixed `synthesize-event' to generate correct relative pointer
     positions

   * Don't focus on non-visible windows (crashes GNOME control center)

   * Fixed bug of using `cp' to install GNOME desktop files

0.25.2
======

   * If no user customization file when saving options, inherit from
     the custom-defaults file

   * Rewrote window stacking (fixes bugs, more efficient)

   * Added `input-focus' to theme-callable functions

   * When focused window is unmapped, don't try to focus non-visible
     windows

   * Fixed `display-window' when it's applied to iconified windows

   * New variables `fonts-are-fontsets' and `fontset-languages-re' to
     work around broken X servers

   * Update edges for snapping to when dragging windows across
     workspaces or viewports

   * When passing keymaps to customization system, filter out, then
     later restore, bindings that aren't symbols

   * Most commands to move/copy windows between workspaces can now be
     told whether to select the destination workspace or not

   * In GNOME hints, never place windows on workspaces that don't exist
     (from the pager's POV). (Rob Hodges)

   * Fixed `ws-move-window' to not remove the window if source and dest
     are the same (Rob Hodges)

   * Fixed `sp-prune-points' function (Dan Winship)

   * Fixed `move-viewport-to-window' to only flip viewports if window
     isn't already on the current viewport (Merlin)

   * Try to detect and handle system clock being rewound

   * Optional second arg to `x-raise-window'; added symmetrical
     function `x-lower-window'

   * Fixed unix-domain server code assuming atomic writes to sockets

   * Added double buffering support to `x' module

   * Fixed grabs during multi-key sequences; also, print the current
     prefix keys if idle during a multi-key sequence

0.25.1
======

   * Only force windows onto the visible screen if they didn't
     explicitly set their position

   * Redefine `/' in themes to be the `quotient' function (integer
     division), which is what they expect. The `divide' function can be
     used for real division

0.25
====

   * New plugin `x', a basic Xlib binding for creating and drawing in
     windows (Merlin, me)

   * Added a method of reading textual input from the user from
     completion. Provision for completing functions, variables,
     commands, files, directories, etc.... Also supports reading
     passwords. (Topi Paavola, me)

   * Re-enabled the following interactive codes: `a' (function), `C'
     (command), `D' (directory), `f' (existing file), `F' (file), `k'
     (event), `n' (number), `N' (prefix or number), `s' (string), `S'
     (symbol), `v' (variable)

   * Support prefix keys in bindings (binding an event to a keymap, or
     the name of a keymap, marks that event as a prefix key for the
     associated keymap)

   * New command `call-command-with-output-to-screen', prompts for and
     invokes a command, then displays any output it emitted (bound to
     `A-x' in default keymaps)

   * New variable `multi-click-delay', maximum time in milliseconds
     between button presses to count as `click2' or `click3' events
     (Martin Blais)

   * New option `edge-flip-only-when-moving' (Yaron M. Minsky)

   * New window cycling commands `cycle-prefix', `cycle-class' (Kai
     Großjohann); can now be bound to events with more than one
     modifier (Timo Korvola)

   * New command `uniquify-window-name'; new property `unique-name'.
     Forces the window to have a unique name

   * New commands `size-window-add-column',
     `size-window-subtract-column', `size-window-add-row',
     `size-window-subtract-row'

   * Window edge snapping now has three variants: `magnetism' (the old
     method), `attraction' and `resistance'. (Merlin, me)

   * New commands `grow-window-{left,right,up,down}' and
     `pack-window-{left,right,up,down}' (Kai Großjohann)

   * Support the `WM_COLORMAP_WINDOWS' protocol

   * New functions `synthesize-event', `font-ascent', `font-descent',
     `call-with-keyboard-grabbed'

   * New functions `define-placement-mode' and
     `define-focus-mode'--make defining these things easier. Focus
     modes are now settable for each window individually

   * Made the tree-organised customization groups work better with the
     GNOME control center. Add the sawmill capplet desktop entries to
     the GNOME programs menu (under Settings). Also, beautify the names
     displayed in the bindings widget

   * When applicable, load the GNOME applications menu when the wm is
     first idle, reduces the latency of displaying the first root menu

   * Translation updates: de (Hubert Nachbaur), es (Iñaki García
     Etxebarria), ja (Sato Satoru), sv (Andreas Persenius)

   * Fix bug of not noticing when the keyboard / pointer / modifier
     mappings change

   * Fixed `current-event-string' function

   * Better method of reconfiguring frames when they're resized (helps
     opaque resizing)

   * Added some kludges to try and break the intermittent lockups some
     people have seen

   * Made the auto-gravity option work a lot better (John N S Gill, me)

   * Fixed bug where unmapped windows were being included in the
     snapping calculation

   * Fixed bug when uniconifying windows and merging workspaces

   * Fixed bug of warp-cursor-to-window trying to put the pointer
     outside the screen boundaries (Merlin)

   * Fixed bug of losing keyboard grab when originally focused window
     is deleted during `x-cycle' command

   * Fixed bug of trying to focus unviewable parent windows when
     focused window is unmapped

0.24
====

   * Configure requests events are now passed to the hook
     `configure-request-hook'. The new configure handler respects
     window gravity when resizing

   * New option `configure-auto-gravity'. When enabled the window
     gravity is implied by the position of the center of the window.
     (e.g.  try placing the GNOME control center in the bottom right
     corner of the screen, then click on an item that causes it to
     resize)

   * Worked around the numerous reports of non-existent font errors
     that using `XCreateFontSet' causes--fall back to `XLoadQueryFont'
     if possible

   * There's now a library `custom-defaults' giving default
     customization options (only if the user has no `~/.sawmill/custom')

     Also, remove the need to call `custom-add-required' in
     `.sawmillrc', it's always done now

   * New window properties `focus-when-mapped', and `gravity'
     (overrides the hinted gravity value)

   * New placement modes `under-pointer' and `centered-on-parent'

   * New option `resize-edge-mode', replaces `resize-by-frame-class'
     and `resize-add-edges'>. Also allows twm-style resizing (Mark
     Probst, me)

   * Optionally display command documentation in tooltips; tooltips are
     now aligned into columns (if you use a monospaced font for them)

   * Variables `default-cursor', `synthetic-configure-mutex',
     `frame-draw-mutex', `frame-state-mutex' are now functions

   * New functions `x-keysym-name', `x-lookup-keysym', `decode-event',
     `encode-event'.

   * New option `move-resize-inhibit-configure'

   * Translation updates: es (Iñaki García Etxebarria), fr (Christian
     Gillot), gl (Jesus Bravo Alvarez), nl (Han-Wen Nienhuys), pt_PT
     (Rui Silva), sv (Andreas Persenius)

   * Fixed single-quoting in client readline (Matt Krai), copied
     bouncing parentheses hack

   * Removed `fp->win == 0' assertion, it should be harmless and was
     triggering for some people

   * Fixed bug of sending configure notify events to too many windows

   * Fixed off-by-one error in `ws-insert-workspace' (Kirk Saranathan)

   * Fixed maximization in single directions to work additively

   * Fixed bug of leaving tooltips displayed after the associated
     window has been deleted

   * Fixed bug of not removing `-clientId' option from restart
     parameters

   * Fixed bug of not translating customize group names

0.23
====

   * Customization groups are now organized as a tree structure, with
     groups able to contain subgroups

   * Define the list of features that will be presented to the user in
     `sawmill-defaults.jl', by calling `custom-add-required'. If you
     have a `.sawmillrc' you'll need to do this manually

   * New function `move-resize-window-to' doing a combined move/resize.
     New variable `synthetic-configure-mutex', when set holds off
     sending synthetic `ConfigureNotify' events to windows until it's
     unset (this is held while interactively moving or resizing windows)

   * New hook `after-add-window-hook'. Called with a single parameter,
     the window that's has just been adopted

   * New functions `x-kill-client', `delete-window-safely'.
     `send-client-message' now groks long integers (i.e. cons cells) in
     32-bit data (Timo Korvola)

   * `window-put', `window-get', `image-put', `image-get', `font-put',
     `font-get': use `equal' to compare keys, not `eq'

   * New module `error-handler', implements a simple alternative error
     handler (and allows the much-maligned beep to be turned off),
     requires rep 0.11+

   * Allow the pointer-warp position to be defined relative to the
     window (Kai Großjohann)

   * New module `shade-hover', unshades windows while the pointer is
     over them

   * Don't automatically warp to the new workspace when opening windows
     on a different workspace

   * Include iconified sticky windows in the `window-menu', shorten
     sticky entries as usual (James Antill)

   * Support the `TryExec' field in GNOME desktop files (Ian)

   * New commands: `raise-or-pass-through-click',
     `raise-and-pass-through-click-if-focused'

   * New module `move-cursor', various commands for moving the mouse
     pointer; these commands are bound to the cursor keys when moving
     or resizing windows

   * Translation updates: es (Iñaki García Etxebarria), fr (Fabien
     Ninoles), gl (Jesus Bravo Alvarez), ja (Satoru Sato), nl (Jan
     Nieuwenhuizen), tr (Fâtih Demir)

   * Fix bug of leaving window-name unset when `WM_NAME' is a null text
     property

   * Don't fail catastrophically if unable to open the default font

   * Fixed method of truncating maximized window dimensions

   * Fixed the match-window `skip-winlist' and `skip-tasklist'
     properties I'd stupidly broken

   * Fixed bug of trying to edge-flip sticky windows

   * Fixed the `move-workspace-forwards' and `move-workspace-backwards'
     commands

   * Fixed `uniconify-to-current-viewport' option

   * Fixed infinite-loop bug in `delete-empty-workspaces' command

   * Avoid generating empty sub-menus when reading GNOME menu tree

0.22
====

   * Window frame parts are now first-class lisp data objects, allowing
     a higher level of control by themes

     New or updated functions to access frame parts directly:

     `frame-part-get', `frame-part-put', `frame-part-window',
     `frame-part-x-window', `frame-part-position',
     `frame-part-dimensions', `frame-part-state', `map-frame-parts',
     `refresh-frame-part', `rebuild-frame-part'

     Other new functions: `refresh-window'

   * Updated `sawmill-themer' to emit code to tell the window manager
     that the theme is editable. The wm adds an `Edit Theme...' option
     to the Customize menu when appropriate

   * The `call-after-property-changed' function can now be given a list
     of properties to monitor (James Antill)

   * New function `call-after-state-changed', monitors a list of window
     states (i.e. things like iconified, shaded, ...) and calls a
     function when any of them change. The `window-state-change-hook'
     now has a second argument (apart from the window), the list of
     symbolic states that changed (James Antill)

   * Add support for `skip-winlist' and `skip-tasklist' to the window
     matcher when GNOME support is enabled (Ben Liblit)

   * Integrated patch supporting multi-byte languages from the Kondara
     MNU/Linux distribution (forwarded by Yukihiro Nakai)

   * Translation updates: de (Christoph Rauch), es (Iñaki García
     Etxebarria), gl (Jesus Bravo Alvarez), ja (Satoru Sato), tr (Fâtih
     Demir)

   * Use a combo box in the configurator to display the list of themes
     (it gets given scroll bars when too big for the screen)

   * Changed timestamp handling--attempt to detect and discard
     timestamps that arrive out of order

   * Added option controlling title justification to `mono' theme

   * Filter <Scroll_Lock> modifiers as well as the other lock modifiers
     (Matt Krai)

   * Fixed `display-message' function update background color, and
     gracefully handle invalid color specifiers (Matt Krai)

   * Reverted to grabbing events on the client window, not the frame,
     avoids some awkward-to-fix-correctly problems

   * Load i18n support _before_ other libraries; ensures that some
     static strings get translated

   * Fixed annoying flicker when cycling to an iconified window

0.21.1
======

   * Fixed problem causing spurious double-click events to be reported
     in click-to-focus mode

   * Fixed problem with binding `-Off' events in the `window-keymap'.
     (Matt Krai)

   * Don't try to grab non-existent keys (which actually grabs the
     entire keyboard)

   * Fixed some problems with reading unusually formatted GNOME menu
     entries

0.21
====

   * Frame pattern definitions (foreground, background, font) may now
     take alists as well as the old single object, or list of four
     objects.  Possible states are `inactive', `focused',
     `highlighted', `clicked', `inactive-highlighted',
     `inactive-clicked'. (Last two are new)

   * New program `sawmill-themer'. A GUI for creating simple themes
     (those without any parts defined by functions)

   * New module `gnome-int', loaded by `sawmill-defaults' if GNOME is
     around, sets up some GNOME'ish things

   * New command `toggle-single-window-mode'

   * Translation updates/additions: de (Christoph Rauch), es (Iñaki
     García Etxebarria), nl (Han-Wen Nienhuys)

   * Optional removal of tooltips after time period (Morgan Schweers)

   * `Any-RET' completes interactive move or resize

   * Work around Imlib's annoying image caching, `make-image' now
     _always_ returns a new image

   * Fixed gc bug when building window frames

   * Fixed X property handling on Alpha's (George Lebl)

   * Make `call-command' accept closures

   * Make `(cursor . nil)' work correctly in frame definitions

   * Grab on frame window, not client window (ICCCM compliant)

   * Fixed the "uniconify to current workspace" option

   * Added window-maximization predicates to the gaol

0.20
====

   * Rewrote workspace handling--windows can now appear on multiple
     workspaces, with each instance having different properties
     (position, size, whatever...)

     Create new window instances by using the `copy-to-next-workspace',
     `copy-to-previous-workspace', and `copy-to-workspace:N' commands.
     Merge instances by moving them to the same workspace, or using the
     `delete-window-instance' command

   * Added linear-viewport commands--indexing two-dimensional virtual
     workspace areas by one-dimensional values (adapted from code by
     Eric Kidd)

   * Rewrote tooltips; especially how they're removed (also, don't show
     null keymaps)

   * Added new match-window property `ungrouped'. Means to put the
     window in a group on its own

   * Translation additions/updates: da (Wandy Christiansen), en_GB
     (me), es (Iñaki García Etxebarria), fr (Christian Gillot), gl
     (Jesus Bravo Alvarez)

   * Fixed bug of not refocusing unshaded windows

   * Fixed bug of not notifying windows of their actual position after
     placing them

   * Fixed bug when grabbing Hyper-modified buttons

   * Fixed the focus-flickering when moving windows opaquely

   * Fixed the `commandp' function when applied to autoload stubs

   * Fixed typo in `gnome-logout' command (Jens Finke)

   * Fixed `raise-window-and-pass-through-click' command to pass
     <click2>, etc, events through to frame parts

   * Fixed infinite-regress bug when reading GNOME menu entries
     (`Type=directory', but actually a file)

   * Fixed bug when showing window-move position with snapped movement
     (adapted from merlin@merlin.org)

   * Fixed bug when matching null text properties

0.19
====

   * Added tooltips for window frames (disabled by default)

   * Added `Grab...' button to match-windows dialogue, grabs the value
     of an X property from a window

   * Support for creating cursors from bitmaps, and for changing the
     colors of cursors

   * Internationalized all strings in the configurator

   * New functions: `frame-part-get', `server-grabbed-p',
     `forget-button-press', `resize-window-with-hints',
     `window-in-workspace-p', `windows-share-workspace-p'

   * New window properties: `never-focus', `raise-on-focus'

   * New pseudo-property (for window matching): `size', in terms of the
     window's size hints

   * Message catalogue additions/updates: Galician (Jesus Bravo
     Alvarez); Danish (Birger Langkjer)

   * Don't ignore initial state property of windows

   * Option to control height of drawn bevels (Chris Hanson)

   * More logical method of drawing diagonal gradients (Chris Hanson)

   * Fixed typo when looking for i18n theme README files (Jesus Bravo
     Alvarez)

   * Fixed `popup-apps-menu' command (Gérard Milmeister)

   * Fixed `define-frame-class' when creating keymaps

   * Fixed conversion of old-style `(set ...)' custom types

   * Fixed `raise-window-and-pass-through-click' command to
     pass-through subsequent clicks

   * Fixed problems when grabbing/ungrabbing customized keymaps

   * Fixed screen corruption when doing wireframe moving and
     `move-resize-raise-window' is set

   * Hacked around window-order problem when sticky windows exist

0.18
====

   * General subsystem for matching windows to properties as they're
     created. Allows matching on one or more of the window's X
     properties (e.g. name, class, etc...), and then setting any number
     of window manager properties as a result. See the `Matched Windows'
     customize group

   * Removed all `auto-FOO-alist' and `BAR-windows-re' variables,
     they're obsoleted by the general match-windows mechanism

   * Respect window's size hints when maximizing (both to see if the
     window is maximizable, and to truncate the maximized dimensions to
     an integral number of rows and columns)

   * Show actual colors in the configurator, not just their names

   * Added a new directory to the theme search path:
     `PREFIX/share/sawmill/themes'. Use this for system-wide themes
     (don't use the version specific directory)

   * Included a new theme `mono'

   * Deprecated the `show-message' function, replaced by
     `display-message' with a better calling interface; also displays
     multi-line strings

   * Deprecated the menu "expand variables when first in list"
     behaviour. Instead expand variables when the list is dotted to
     them, as is done for functions

   * Support the `Hyper' modifier, prefix is `H-'

   * In the configurator, look for i18n'd theme README files (Yukihiro
     Nakai)

   * Added option to disable the ability to grab a second edge while
     resizing (`resize-add-edges')

   * Included Danish message catalogue (Kenneth Christiansen)

   * Renamed `fixed-position' property as `sticky-viewport', and
     `focus-proxy-click' as `focus-click-through'

   * When evaluating mouse events, look in the window that the pointer
     was in when the button was pressed, not where the pointer
     currently is

   * Fixed bug where focus gets totally lost after closing a Motif
     application that has grabbed the keyboard

   * Fixed (again) the problems when handling remapped windows; also
     should be more ICCCM-compliant

   * Fixed typos in one-dimensional maximisation (Gérard Milmeister)

   * Fixed the logic deciding when it's necessary to switch workspaces
     after merging an empty one

   * Fixed interactive placement showing the window when edge-flipping
     (but it still doesn't work properly, rubber band traces are left)

   * Removed flicker when focusing already-focused windows

0.17
====

   * First version to use lexically scoped librep. This enables themes
     to run in a "safe" environment, but all existing themes will need
     to be ported; other language changes include the use of a single
     symbol namespace, and scheme-like function call semantics

   * Support for internationalization of messages and run-time
     documentation; an en_GB catalogue is the only translation
     currently, so please send me .po files for your native languages!

     New option `--disable-nls' to disable i18n

   * New functions `call-after-property-changed' and
     `gtkrc-call-after-changed' to allow themes to receive these events
     (hooks are now off-limits to themes)

   * New command `raise-window-and-pass-through-click'; bind it to a
     mouse button in the `window-keymap' to get the "raise window on
     click" behaviour that seems popular

   * New commands to move windows incrementally: `slide-window-X' and
     `slide-group-X' for X one of: `left', `right', `up', `down'

   * New commands to control `ignored' property of windows (Julian
     Missig)

   * New commands to toggle GNOME skip-winlist and skip-tasklist
     properties of windows

   * Respect window gravity with program-specified window placement
     (<merlin@merlin.org>)

   * Fixed a memory leak in the `stacking-order' function

   * Fixed the `bevel-image' function (Scott Sams)

   * Never look in the focused window's keymap by default with mouse
     events

   * Hacked around the "need an X11 connection to compile" misfeature

   * Fixed bug in `gnome-menu' code when GNOME binaries aren't in the
     first $PATH item; also accept non-alphanumeric language codes

   * Fixed interactive window placement (again)

   * Rewrote obscure documentation for some custom options

   * Fixed bug when grabbing events with `AnyModifier' and a specific
     button

0.16
====

   * Support window groups, both as defined by applications, and
     defined by the user (either interactively through the window's
     menu, or via the `auto-group-alist' and `persistent-group-ids'
     variables).

     For most commands working on single windows, there's also one
     operating on the group that the current window is a member of.
     (With the notable exception currently of moving windows.) There's
     also options controlling whether (de)iconification operates on
     windows or groups

   * Improved GNOME menu support--merge duplicate sub-menus, scan PATH
     for `gnome-share-directory', also look in `/etc/X11/applnk' for
     menu entries

   * Option to control whether edge-flipping flips viewports or
     workspaces (`edge-flip-type')

   * New hook `after-framing-hook': called whenever a window's frame is
     changed or recalibrated

   * New window placement mode: `first-fit-or-interactive'

   * Variables specifying common cursor shapes: (`move-cursor-shape',
     `resize-cursor-shape', `select-window-cursor-shape')

   * Fix interactive placement

   * Fix problem of window losing focus when `cycle-windows' only finds
     a single window; also, abort immediately if there's no windows to
     cycle through at all

   * Fix how the `WM_NORMAL_HINTS' property is read after it's been
     updated

   * Fix `maximize-fill' functions to respect the
     `maximize-ignore-when-filling' option

   * Fix interactive move/resize aborting if keyboard is already grabbed

   * Ungrab the keyboard as well as the pointer before popping menus

0.15
====

   * Changed how themes are loaded from tar files--the tar file must
     now contain a directory with the same name as the theme; it's this
     directory that stores the data files

   * Allow viewport edge-flipping to be enabled by the customization
     system, also enable flipping while moving windows

   * Unified the method of marking which windows should be avoided when
     maximizing, and which windows should be avoided when using the
     fitted placement methods. Set the `avoid' property instead of the
     `maximize-avoid' property; new functions `window-avoided-p' and
     `avoided-windows'; new regexp `avoided-windows-re'

   * New command `delete-empty-workspaces'

   * Default theme is now `microGUI'

   * When resizing only one edge of a window, moving the pointer past
     one of the perpendicular edges grabs that edge also

   * Only the first three buttons focus a window in click-to-focus mode

   * Changed behaviour of `window-id' and `window-frame-dimensions'
     functions. Replaced `query-last-pointer' function by
     `query-button-press-pointer'

   * New hooks: `while-moving-hook', `while-resizing-hook'

   * Notice when `WM_TRANSIENT_FOR' property changes

   * More bug fixes to the maximization code, mainly for efficiency;
     also make first-fit placement work from top-left again

   * Fix bug when matching events with `Any' modifier as well as other
     modifiers

   * Fix bug in `window-outside-viewport-p' (Andreas Degert)

   * Fix bug in `sawmill-client --' with long inputs

   * Fix bug when matching windows with session data--`SM_CLIENT_ID' or
     `WM_COMMAND' _has_ to match

   * Fix bugs when passive grabbing non-button-press pointer events

0.14
====

   * Rewrote window-maximization, many new options

   * New option `resize-by-frame-class', when enabled (the default),
     the resized window edges are chosen to match the class of the
     clicked frame part (i.e. matching the cursor shape)

   * Load GNOME support code automatically if it looks like GNOME is
     being used

   * Create unix-domain sockets in `/tmp'

   * New hooks: `window-moved-hook', `window-resized-hook',
     `after-initialization-hook', `shape-notify-hook'.

   * Improved how menus are displayed; the window-ops menu is shown by
     ButtonPress not ButtonRelease events

   * Refocus most-recently-focused window when switching viewport

   * Added `centered' placement style

   * Added symbol-completion to readline-based client

   * Fix bug of not noticing WM_NORMAL_HINTS property changes; follow
     the window's maximum size hints

   * Fix bug of not reframing windows when they change from unshaped to
     shaped, or vice versa

0.13
====

   * New option to only highlight frame parts when their window is
     focused (`highlight-when-unfocused')

   * Typing `ESC' while moving/resizing a window cancels the operation,
     restoring the original geometry

   * New session management hook `sm-after-restore-hook'

   * New function `set-frame-part-value'--makes customizing the
     `frame-part-classes' variables easier

   * Support for loading themes from tar files; needs librep 0.7

   * Fix bug when allocating colors (choosing an incorrect cached color)

   * Fix image tiling in frame part backgrounds

   * Handle shifted keysyms when passive grabbing

   * Fix another race condition when active grabbing

   * Fix `_WIN_CLIENT_LIST' property not being set properly (both
     missing windows immediately after they're adopted, and of
     intentionally skipping ignored windows)

   * Fix some problems with viewports when exiting/restarting

   * Fix broken stacking of windows after they're mapped

   * Prevent smart window placement blowing up when large numbers of
     windows are open/opened (throttle back to random placement when the
     event queue is too large, as well as trying to prune the search
     space)

0.12
====

   * Remember most recently focused windows on each workspace, activate
     that window after changing workspaces; also, try to preserve focus
     when moving windows between workspaces

   * Option to disable auto-raise while cycling through windows
     (`cycle-disable-auto-raise'); option to restrict cycling to the
     current viewport (`cycle-all-viewports')

   * Option `lock-first-workspace' is now enabled by default, and
     prevents both the first and last interesting workspaces being moved
     inwards

   * Added readline support to the client program, pass
     `--with-readline' option to configure (from Christopher P Goller
     <goller@eng.utah.edu>)

   * Added shaped-transient frame to microGUI theme

   * New frame part attribute `below-client'

   * Release passive grabs when unadopting windows

   * When no window has the focus, the `root-window-keymap' is searched
     for key-press events

   * Fix bug when binding to the unix-domain socket

   * Fix focus sometimes being lost when the focused window is destroyed

   * Fix bug when reading GNOME menu entries without `Type' fields

   * Fix bug when removing title or border of `shaped-transient' window
     types (make the window completely unframed)

   * Fix bug when shading a transient window with `decorate-transients'
     enabled

   * Fix some bugs when placing windows that are almost as big or
     bigger than the screen

   * Fix some race-conditions between wm-generated and client-generated
     map/unmap/reparent events

   * Fix infamous "jerky pointer" bug, this will also make overlapping
     shaped frame-parts display correctly

   * Fix bug where `cycle-windows' could leave a window originally
     under the pointer that's unfocused, drawn as though it is focused

0.11
====

   * New option `lock-first-workspace', prevent the first workspace
     from being deleted when it's empty

   * New option `ignore-window-input-hint', to always give windows the
     focus, whether they say they will accept it or not

   * New options when cycling windows: `cycle-warp-pointer' and
     `cycle-focus-windows'

   * Restore the old method of setting the focus, should fix bug of
     losing focus totally when switching to a new workspace

0.10
====

   * Implemented virtual workspaces, bind to the `move-viewport-X' and
     `move-window-X' commands (for X being `left', `right', `up', or
     `down')

   * Added a new theme: `microGUI' by Ryan Lovett
     <ryan@ocf.berkeley.edu>, based on the QNX Photon screenshots

   * Added a `Grab key' button in the bindings widget, replaces the
     current binding with the next pressed key

   * Lisp module to load the GNOME menus and use them to replace the
     applications menu. Add `(require 'gnome-menu)' to your
     `~/.sawmillrc' file to load it

   * Network server is disabled by default (since it can provide a
     security hole if X access control is disabled); re-enabled the old
     unix domain socket code (see the FAQ for more details)

   * Only give the input focus to windows that actually want it

   * New option to keep transient windows above their parents
     (`transients-above-parents')

   * New option to control how the workspace boundary is handled when
     moving windows between workspaces (`workspace-send-boundary-mode')

   * New commands `send-to-workspace:X' for X from 1 to 9

   * While windows are hidden or shaded, unmap the client (for ICCCM
     compliance)

   * Slightly different method of handling destroyed clients, hopefully
     results in fewer annoying error messages

   * Support X installations without X11R6 session management (by not
     doing any session management)

   * Don't ask the session manager to save our environment

   * Fix bug where a window is destroyed/unmapped while it's being
     resized or moved

   * Fix bug where window can still be auto-raised even if it's been
     defocused

   * Fix problems when `--prefix' option has a trailing slash

   * Now handles client windows being reparented by a third party (i.e.
     swallowing apps)

0.9
===

   * The first-fit and best-fit algorithms are now much more
     intelligent, e.g. instead of falling back to random placement when
     a window can't be placed without overlapping an existing window,
     they will attempt to minimize this degree of overlapping

   * The `foreground' property of each frame part may now be an image
     instead of a piece of text

   * New theme `smaker', uses the foreground images capability to do a
     somewhat WindowMaker-like theme (with the absolute-e images). This
     theme is extensively customizable--all images, colors, dimensions,
     etc...

   * Use Imlib's fuzzy color matching for all color allocation; this
     should help on `PseudoColor' visuals

   * Added an `xterm' command to launch an xterm

   * Improved the bindings customization widget layout; added a `Copy'
     button to insert a copy of the current binding

   * Added `next-workspace-row' and `previous-workspace-row' commands.
     Together with the `workspace-columns' variable these mimic a 2d
     desktop

   * Removed the `cycle-through-workspaces' option, there's now
     `workspace-boundary-mode'--one of `stop', `wrap-around' or
     `keep-going'

   * Added option to include ignored windows when edge snapping
     (`move-snap-ignored-windows')

   * Fix race condition between startup of sawmill and gmc; sawmill now
     has earlier priority

   * Fix seg fault when running out of color cells while generating a
     window frame

   * Fix bug where the window-workspace mapping wasn't reloaded from
     saved sessions

   * Fix cancel/revert problems in bindings widget

   * Fix problems binding to shifted keys when using the XKEYBOARD
     extension and XFree86

   * Be ICCCM compliant when a client requests to be moved

   * Fix crash when tiling small images into large images

   * Fix bug where windows could be snapped totally off-screen

   * Fix bug when windows change their `override_redirect' attribute
     while unmapped

   * Fix bug associated with WordPerfect's menu window

0.8
===

   * First attempt at best-fit window placement (doesn't really work
     properly yet...)

   * Added a customization option to focus windows when they're
     un-iconified (`focus-windows-on-uniconify')

   * Fix bug in click-to-focus mode where the click is only passed
     through to the client window, not to any local bindings of the wm

   * Don't leave windows unframed if there's an error in the user's
     startup files

   * Fix bug in `preallocated-workspaces' option

   * Don't place windows off-screen in first-fit mode

0.7
===

   * Added stack-based window cycling, bound to `M-TAB' by default.
     Hold <Meta>, keep pressing <TAB> until the correct window is
     reached, then let go of <Meta>.

   * Added first-fit window placement (a.k.a smart-placement)

   * Completed first stage of workspace rewrite--shouldn't go ballistic
     when windows are removed anymore

   * Added `override-frame-part-classes' variable--allows all frame
     properties to be overridden on a per-class basis

   * Click-to-focus now accepts any button and any modifiers

   * Don't snap to gmc icons or panels

   * Added an `auto-window-type-alist' variable mapping window names to
     border types

   * New variables `eval-modifier-events' and `eval-key-release-events'
     to allow catching these types of keyboard events, disabled by
     default

   * Added functions for actively grabbing the keyboard

   * Removed the long names of the keyboard modifiers, only the single
     character modifiers are left

   * If no alt modifier, set it to the same as meta; new variables
     `alt-keysyms' and `meta-keysyms' describe the virtual modifier
     assignments

   * Fix bug when handling shaped frame parts--it was possible to go
     into a long enter-, leave-notify loop when the old shape was
     cleared

   * Fix bug where opaque resizing with snap-to-edges on moved the
     window as well as resizing it

   * Fix bug when raising the only managed window

   * Fix bug where very small client windows got weirdly shaped frames

0.6
===

   * Define the standard "classes" of frame parts (i.e. things like
     close button, title, left border, etc...) then allow the state of
     members of these classes to be set in one place (the
     `frame-part-classes' variable). This should ensure that different
     themes have the same feel (but a feel that may be customized by the
     user)

   * Allow frame parts to be removed if possible (if they have the
     `removable' property). Nothing makes use of this yet

   * Added window-shading, double-click button1 on the title bar

   * Created a sawmill capplet for the GNOME control center. Use the
     `--enable-capplet' configure option to build it

   * First attempt at a technical manual (very quickly written, so
     probably some inaccuracies)

   * In the `gtk' theme, draw bevels on window decorations

   * Use spin-buttons in the configurator to enter numbers

   * Add option `focus-proxy-click' controlling whether to pass the
     focus-inducing button-press event to the underlying window (in
     click-to-focus mode)

   * Changed the bindings in window borders, it's now the more usual
     button1 to resize, button2 to move

   * When clicking and dragging windows, ensure that the clicked frame
     part stays clicked until the button is released

   * If in click-to-focus mode, and there's no parent window to focus
     when the focused window is closed, focus the topmost window (not
     the window under the pointer as in the other focus modes)

   * Changing window frames is _much_ less ugly, no flicker at all!

   * Try to optimise window restacking some more

   * Sped up opaque window moving when the position display is enabled

   * Preserve iconified state across restarts

   * Optimise updating the shape of an unframed window (this stops gmc
     icons flashing annoyingly)

   * Fix bugs in click-to-focus mode where some windows were
     un-focusable

   * Fix bug where cycling through windows in click-to-focus mode
     didn't focus the activated window

   * Fix bug where comparing sawmill lisp objects caused a crash

   * Fix bug where initiating a resize in the middle of the window
     didn't allow any of the edges to be moved

   * Fix bug where changing the "decorate transients" option didn't
     alter any existing transient windows

   * Fix bug where iconifying a sticky or ignored window gave no way of
     reclaiming it--these windows now appear at the end of the window
     menu

0.5
===

   * Now does session management. The scheme is extensible, arbitrary
     Lisp modules can save and restore window state due to their own
     functionality (using the `sm-window-save-functions' and
     `sm-restore-window-hook' hooks). See `lisp/workspace.jl' for an
     example

   * Displays window position or dimensions whilst interactively moving
     or resizing a window (`move-show-position',
     `resize-show-dimensions')

   * Mechanism for setting frame styles on a per-window basis (this was
     always possible, just not easy). The `auto-frame-style-alist'
     variable associates window name regular expressions with frame
     styles.  Also, the `window-ops-menu' has a new submenu with all
     possible styles

   * New option `preallocated-workspaces', the number of workspaces to
     create at startup

   * Window-workspace mapping is preserved through restart (as long as
     the GNOME hints are enabled)

   * Theme directories may contain a short `README' file that will be
     displayed in the configuration tool

   * Changed the custom file to `~/.sawmill/custom' instead of
     `~/.sawmill-custom'. The old file will be moved to the new
     location if it exists

   * Install `sawmill-menu' under `libexec' since it shouldn't be run
     manually

   * Option in `gradient' theme to create full-sized gradient images,
     trading memory for quality

   * Workaround the flicker when raising windows

   * Changed most of the `menus' and `custom' customize options into
     normal variables (they're not particularly intuitive)

0.4
===

   * Frame parts can now be highlighted when the mouse is over them,
     also they "un-click" and "re-click" as the pointer leaves and
     re-enters their window. ButtonRelease bindings are only activated
     when the mouse is in the window at the time

   * Frame part backgrounds can now be rendered on-the-fly using the
     new `renderer' property in frame definitions. This property is a
     function called with args `(IMAGE STATE)'; it should draw a
     background into IMAGE for the specified state (`nil', `focused',
     `highlighted' or `clicked')

   * New theme `gtk'. This reads the default GTK style and uses the
     associated colors and pixmaps to decorate windows. It doesn't try
     to handle engine-based themes. It should automatically detect when
     the default style changes (if changed by the GNOME control
     center). Do `sawmill-client -c gtk-reload-style' in the shell to
     reload the style manually

   * Functions for drawing color gradients and bevels into images. The
     new `gradient' theme uses these and on-the-fly rendering to do
     `afterstep'-like window titles

   * Configurator changes: use a paned widget to separate the list of
     groups from the settings (stops their relative sizes changing),
     allow each group to be customized separately, either through a new
     set of root-submenus or the commands `customize:GROUP' for each
     GROUP.

   * Changed the way that "themes" are organised, each theme now gets
     its own directory, which must include a `theme.jl' or `theme.jlc'
     script to initialise a frame-style of the same name as the
     directory. While this script is being evaluated the image path is
     set so that the theme can load any images stored in its directory.

     Also created the variable `theme-load-path' containing the list of
     directories searched when trying to load a theme. By default it
     contains two directories: `~/.sawmill/themes/' and
     `PREFIX/share/sawmill/VERSION/themes'.

   * Resizing now chooses the direction to resize the window in by the
     initial position of the pointer in relation to the window. The
     window is divided into a 3x3 grid, the pointer must be in one of
     the outer rectangles to resize in that direction

   * New commands `select-workspace:X' for X between 1 and 9

   * Support multiple depths, or layers, of windows

   * It's now possible to move the current workspace up or down the
     list of all workspaces

   * New option `-c COMMAND' to `sawmill-client'; invokes the named
     interactive function

   * When an app asks for no title and no border, give it what it
     wants--use the new `unframed' window type

   * The maximize button works

   * Option to control placement of transient windows
     (`place-transient-mode')

   * Changing the frame style preserves the original window stacking
     order

   * Added documentation strings for most built-in functions

   * Fix bug of evaluating both KeyPress _and_ KeyRelease events

   * Fix bug of making the shape mask of unshaped client windows too big

   * Fix bug where already-handled BadWindow errors were being reported

   * Fix bug where the `window-ops-menu' could be displayed from one
     window but then affect a different window

   * Fix bug where click-to-focus doesn't work for new windows

   * Fix bug where deleting the last workspace selected the first, not
     the new last workspace

   * Fix bug where changing a colormap when no window is focused causes
     a segfault

   * Fix bug where iconifying a window may leave it in the clicked
     state after it's uniconified

   * Fix Caps_Lock and Num_Lock modifiers interfering with bindings

   * Fix accessing X properties on 64-bit architectures

   * Fix bug where pointer may be left grabbed after moving a window

0.3a
====

   * Support the maximized GNOME window states

   * Where available, show documentation strings of commands in the
     configurator

   * Improve the method of handling clicks in frame-parts

   * Fix asynchronous client-server protocol

   * Fix interactive window moving/resizing (don't leave traces of the
     rubber-band, stop the window initially "jumping" to the pointer)

0.3
===

   * Implemented window maximization

   * Added support for snapping to window edges when interactively
     moving windows (`move-snap-edges' and `move-snap-epsilon')

   * First attempt at handling a subset of the Motif and OpenLook
     window hints

   * Removed the `sloppy-focus' variable, it's replaced by
     `focus-mode'. This can currently be one of `enter-exit' (normal
     focus follows pointer), `enter-only' ("sloppy" focus) or `click'
     (click to focus)

   * When resolving pointer events, scan the `keymap' property of the
     window under the pointer, not the focused window (as with keypress
     events)

   * The `sawmill-client' program can now communicate inter-host, since
     it uses X properties not raw sockets

   * New hook `before-exit-hook', called immediately before shutting
     down

   * Rewrote the GNOME support as a Lisp module

   * Placing windows interactively now works

   * Fixed the bug on Solaris where deleting windows could cause a
     segmentation fault

0.2
===

   * Added a user-customization system, inspired by Emacs' customize
     facility. Invoke this through the `sawmill-ui' program, or from
     the `Customize...' entry in the main menu. All changes are stored
     in the Lisp script `~/.sawmill-custom'

   * Selected windows may now be raised (`raise-selected-windows')

   * It's possible to prevent the mouse pointer being warped to
     selected windows (`warp-to-selected-windows')

   * The `brushed-metal' and `simple' themes now define all four
     standard frame types

   * Frame themes are now stored in a separate directory
     (`PREFIX/share/sawmill/VERSION/lisp/themes') so that the list of
     all available themes can be made automatically

   * The frame colors of the `simple' frame style can now be customized
     (`simple-normal-color' and `simple-active-color')

   * The `sawmill-defaults.jl' script enables GNOME compliance
     unconditionally (since it has no ill-effects even if GNOME isn't
     being used)

   * Transient windows can be given the same frames as normal windows
     (`decorate-transients')

   * Newly-displayed transient windows can be automatically given the
     focus if their parent window is focused (`transients-get-focus')

   * Any newly-displayed windows can be automatically given the input
     focus (`focus-windows-when-mapped')

   * The `foreground', `background' and `font' attributes of each frame
     part may now refer to a function

   * Fixed the window-move bug whereby the first motion event was
     discarded

   * Fixed the bug where windows may be placed partially off the root
     window, even if they needn't be

   * Fixed the shaped frame parts bug (they didn't work)

   * Miscellaneous other bug-fixes

0.1
===

First proper release

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.

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, see 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 (librep).

   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, see 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.

Frequently Asked Questions
**************************

  1. Why is it now called _Sawfish_?

     Because the old name (`Sawmill') was already being used by another
     company, who were in the process of registering it as a trademark.

     The rename should be mostly painless, all old binaries still work
     for the time being, but will be phased out over time. Where before
     you would execute a program called `sawmill*', replace it by
     `sawfish*'. E.g. `sawmill' becomes `sawfish', and `sawmill-client'
     becomes `sawfish-client'.

     Your `~/.sawmill' directory will automatically be renamed
     `~/.sawfish' unless it would overwrite an existing file. Both
     `~/.sawfishrc' and `~/.sawmillrc' will be checked currently
     (though only one will be actually loaded).

     My apologies for any inconvenience caused.

  2. But why _Sawfish_, and not <insert your favourite alternative>?

     Well I had to choose something! And hopefully it satisfies the main
     requirements:

        * There are no other computer-related users of the name (as
          checked in April 2000,)

        * It's similar enough to the old name to hopefully carry some
          recognition across,

        * It has no tenuous relationship to window-managing.

  3. I installed Sawfish but it's not working!  All I see when I start
     X is the default stipple background: no programs, no menus, no
     pager.

     This is exactly what it's supposed to do. Sawfish is a _window
     manager_ and as such is not responsible for setting the background,
     starting programs or displaying a pager--these can all be done
     using separate applications (e.g. by using a desktop environment
     such as GNOME).

     The default menu binding is somewhat obscure; you must
     middle-click on the background to bring up the menus. (If you have
     a two-button mouse, try clicking both buttons simultaneously)

     If, after reading this, you still think that sawfish isn't working,
     please send mail describing the problem to the sawfish mailing list
     <sawfish@lists.eazel.com>

  4. How do I add customizations?

     There are several files controlling this:

    `~/.sawfishrc'
          Hand written lisp code, loaded at startup. This is where
          almost all explicit customization should be done.

    `sawmill-defaults'
          This lisp library is only loaded if there's no `.sawfishrc'
          file.

    `~/.sawfish/custom'
          This stores customizations created by the configuration tool;
          it shouldn't really be edited manually.

          This file is loaded _after_ `sawmill-defaults', but _before_
          `.sawfishrc'.

  5. I created `.sawfishrc', now things have changed?

     If a `~/.sawfishrc' file exists, it prevents `sawmill-defaults'
     from being loaded. But it's `sawmill-defaults' that loads some of
     the common window manager features, so add the line

          (require 'sawmill-defaults)

     to your `.sawfishrc' file if you want to start with all the
     standard features loaded.

  6. What's this `sawfish-client' program?

     This allows you to connect to a window manager process and evaluate
     arbitrary Lisp forms. Do `sawfish-client -?' for more details
     (`sawfish-client -' for a read-eval-print loop)

     By default you can only connect from the host running the wm
     (through a unix-domain socket). To enable the network based
     server, evaluate the lisp form `(server-net-init)'.

     Note however that this connects through the X server, meaning that
     anyone who can open windows on your display can also execute any
     Lisp code on the host running the window manager (and by extension,
     _execute any program_).

     So _don't_ run the net server with X access control disabled
     (unless you're not connected to a network)

  7. How do I bind a key to execute a shell command?

     Bind a key to the `run-shell-command' command; remember to enter
     the shell command you want to execute in the string entry in the
     `Edit binding' dialog window.

  8. How do I make clicking on a window raise the window?

     Bind the event `Button1-Click1' in the `window-keymap' to the
     `raise-window-and-pass-through-click' command

  9. How do I redefine the `Applications' menu?

     See the `Popup Menus' node in the Info manual (see Popup Menus)

 10. How do I read the Info manual?

     Either execute the command `info sawfish', or enter the Info mode
     within Emacs (`C-h i') and type `g (sawfish) RET'.

     If you're using GNOME, then try executing `gnome-help-browser
     info:sawfish'.

 11. How do I create a new theme?

     See the `Window Frames' node of the Info manual (see Window Frames)

     Basically though, create a directory `~/.sawfish/themes/FOO' where
     FOO is the name of your theme. Then copy any images into this
     directory and create a file `theme.jl' that will be loaded to
     initialise the theme

     The configuration tool will display the contents of a file called
     `README' in the directory (but make it 80-column text, and only a
     few lines)

     Recent versions of sawfish include a program `sawfish-themer' that
     allows simple themes to be created using a GTK+ interface. Ian
     McKellar has created `GimpMill':

          GimpMill is a GIMP plugin written in Python using James
          Henstrige's really cool Python GIMP bindings. It allows the
          construction of Sawmill themes within The GIMP - extending
          the GIMP interface to allow theme creation like the GAP
          extends it to allow animation creation.

     GimpMill is available from
     <http://www.yakk.net/projects.gimpmill.html>

 12. How do I port an Enlightenment theme to sawfish?

     There's no automatic translation available. Get the images used in
     the window border, then write a `theme.jl' file telling the window
     manager how they are used to form a window frame

     See the `themes/brushed-metal' directory for an example, and the
     Info manual for the documentation

 13. Are there any other themes available?

     Thanks to those nice people at themes.org, there's now
     <http://sawmill.themes.org/> for your theming pleasure

 14. Why don't GTK themes work with sawfish?

     There was a problem with older versions of the `gtk-engines'
     package preventing engine based themes working with several
     interpreted languages. Get the latest `gtk-engines' from
     <ftp://ftp.gnome.org/>

 15. Why don't you use GUILE?

     Mainly because I'm lazy; I had already written rep, and therefore
     understood it completely, whereas I have never used GUILE. Also,
     rep has some features not available in GUILE (byte-code
     compilation, autoloading, built-in event-loop, ...)

     But before you flame me: yes I do think scheme is a more elegant
     language

 16. Will you add feature X?

     Possibly. But only if it can be written in Lisp, or doesn't
     conflict with the overall design aims.

     These aims are to build a lightweight, generally applicable, set of
     core window management functions, then write _all_ high-level
     functionality as Lisp extensions

 17. Will you add background setting?

     No. This can easily be done by a separate application (e.g. with
     the GNOME hints, simply monitor property `_WIN_WORKSPACE' on the
     root window).

 18. Is there a sawfish mailing list?

     Yes. See <http://lists.eazel.com/mailman/listinfo/> for
     subscription instructions and archived messages.

 19. Is there a sawfish IRC channel?

     From Ryan Pavlik <rpav@mythosource.org>:

          Sawmill has an irc channel too! It's on EFNet, and called (of
          all crazy things), #sawmill. So break out your irc clients,
          or hop on over if you're already addicted. Theme, lisp,
          general sawmill, and most other random discussion welcome.

          If you need an EFNet server, check www.efnet.net for a
          listing.

 20. Why does sawfish look weird/crash on Solaris?

     Sawfish works stably on Solaris, but you may need to do two things:

       1. Disable use of MIT-SHM by Imlib (run the program
          `imlib_config', the MIT-SHM option is on the `Rendering' page)

       2. Recompile GTK+ using the `--disable-xim' option to configure

 21. Why don't some windows ever get focused?

     If you don't have the option `give focus to windows even when they
     haven't asked for it' checked (group Focus/Advanced), then windows
     that don't ask for focus don't get it.

     Windows ask to receive focus by setting their WM_HINTS property
     appropriately; for example if I xprop a gnome-terminal:

          WM_HINTS(WM_HINTS):
                          Client accepts input or input focus: True
                          Initial state is Normal State.
                          window id # of group leader: 0x5c00001

 22. Why doesn't the GNOME desk-guide / tasklist show the true state of
     my desktop?

     It seems that there is a problem with these applets that only
     occurs after restarting sawfish-they seem to lose track of the
     current window states.

     The simplest way to correct this is to execute the following shell
     commands:

          $ save-session
          $ killall panel

     (assuming you have a session manager to restart the panel
     afterwards!)

 23. What do these `bytecode-error' messages mean?

     It means that you're trying to execute Lisp code that was compiled
     for an outdated version of the Lisp virtual machine. Recompile any
     Lisp files that you have installed locally.

 24. How do I compile Lisp files?

     Use the shell command:

          sawfish --batch -l compiler -f compile-batch FILES...

     where FILES... are the names of the files you want to compile.
     They will normally have `.jl' suffixes, the compiler will create
     associated files with `.jlc' suffixes containing the compiled Lisp
     code.