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.
Sawfish is copyright (C) 1999 John Harper and is released under the
terms of the GNU General Public License. See the included file
COPYING for the full text of the license (or see Copying).
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.
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 Top), this is a run-time library implementing a language similar to Emacs Lisp (see Top), but with many extensions, and using lexical instead of dynamic scope. This manual assumes at least a basic knowledge of the language.
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.
sawfish.wmfor window manager code,
sawfish.uifor configurator and
sawfish.gtkfor 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
autoload-command add entries to this
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-clientnow provides the same repl as the normal
repprogram. 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.clientmodule 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
ConfigureRequestevents in a way that is compliant with the ICCCM--honour the window's
win_gravitysetting (defaulting to
NorthWestgravity), instead of assuming
sawfish.wm.util.xplugin (Ryan Pavlik)
To support this, new window property
desktop denoting a
"desktop" window; new function
one of these things (or the symbol
pointer-motion-thresholdoption. 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
select-workspace-and-viewport. Renamed some workspace functions:
get-visible-window-edgesfunction to use proper keyword parameters, and added some new keywords
gnome-about. Added a
sawfish-aboutscript to implement the first of these. Added associate menu items to the `Help' menu
throwout the top of the program by mistake
find-headfunction, to allow Xinerama support to work
synthesize-eventto scan the window tree for a child window accepting button events (E. Jay Berkenbilt)
image-setand related functions will add an alpha channel to the image when necessary (when using gdk-pixbuf)
quote-menu-itemfunction to help with this)
setmethod of the
hiddenattribute, ignore it
FIXED_POSITIONGNOME hint (renamed old
fixed-positionnow means don't allow the window to be moved by the user)
transients-aboveoption can now be set per-window
defcustomalways causing the module to be loaded, not just when the option is non-nil
quote-eventcommand now works with applications that ignore synthetic events (adapted from code by Timo Korvola)
define-frame-type-mapperallows 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)
variable-customized-p; use this to avoid redefining user-modified options
: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)
default-bevel-percentwas being ignored)
move-window-to-viewportcommand to correct for 1... indexing
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
WM_TRANSIENT_FORproperty to the root window denotes that the window is a transient for the whole group
image-map. New color accessor function
color-rgb-8. New function
sawfish-ui: optionally use some GNOME widgets, more lisp widget types, some bug fixes
command-sequence. Allows individual bindings to invoke a sequence of commands
uniconify-whole-group. New commands
:type, but value is left unquoted
WM_NORMAL_HINTS(was using base-size instead of min-size in places)
window-historymodule won't resize a window to a size that violates its size constraints
match-windowoptions). Also, extra widget types and containers may be added as extra Lisp modules
Trybutton to be pressed
cursorattribute may now be a function
under-pointerplacement modes clamp the window into the current work area (i.e. without overlapping windows that shouldn't be covered). Added a
placementgroup. Fixed some more bugs and sub-optimal default option values
SKIP_FOCUSwindow hint sets
never-focusproperty on window, as well as the
--depth=DEPTH. These tell the window manager to use a different visual than the default
window-historymodule behave more sanely (don't save iconified or shaded state; include window name when generating keys for transient windows)
beos-window-modulethe standard window menu (require
old-window-menuto get the original version). Also made this display the windows' class names
window-history--automatically saves window attributes when they are explicitly set by the user, then copies these attributes to windows with the same
WM_CLASSas they are created. This is loaded automatically if you have no
frame-type-fallback-alistmaps 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
best-fitplacement mode user-controllable. Set the
sp-cost-componentsvariable 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
beos-window-menuto 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)
edge-flip-warp-pointer, whether or not to warp the pointer after edge-flipping (Paul Warren)
display-window:uniconify-to-current-workspace, controls whether windows uniconified by
display-windowshould be moved to the current workspace (John N S Gill)
xlibrary now supports creating and then drawing to pixmaps. The pixmaps can then be grabbed to images using the
Helpitem to the root menu
cycle-windowssequence 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)
LANG=de_DElook for both
raise-groups-on-focusoption, it caused unstable window flickering in certain cases
sawfish; all user-visible binaries have been renamed appropriately, the old programs will still work for now...
current-head-offset. Some placement modes should handle multiple heads sensibly, as should window maximization and edge snapping.
lower-groupto preserve the stacking of the group, then change the selected window. Added new command
workspace-menuto add the focus-marking asterisk (John N S Gill)
WM_STATEproperty is set each time a window is mapped, not just the first time
selection, adds functions
x-get-selectionfor retrieving X selections (Mark Probst)
window-animmodule enabling asynchronous animations after window events. Currently only two animation styles
solid, and they only animate window iconification
audio-eventsmodule; maps window manager events to audio samples (played using esd by default, but can be configured to use any program)
xterm-programto decide which terminal program to use (James Antill)
zhlanguages need FontSets
randommode; also increased
sp-avoided-windows-weightby an order of magnitude (Dan Winship)
get-cursorto use the correct background color when creating cursors from vectors (Alexander Barinov)
get-fontto set `descent' property correctly
xplugin, also only support this if configure finds the correct header files
synthesize-eventto generate correct relative pointer positions
cpto install GNOME desktop files
input-focusto theme-callable functions
display-windowwhen it's applied to iconified windows
fontset-languages-reto work around broken X servers
ws-move-windowto not remove the window if source and dest are the same (Rob Hodges)
sp-prune-pointsfunction (Dan Winship)
move-viewport-to-windowto only flip viewports if window isn't already on the current viewport (Merlin)
x-raise-window; added symmetrical function
/in themes to be the
quotientfunction (integer division), which is what they expect. The
dividefunction can be used for real division
x, a basic Xlib binding for creating and drawing in windows (Merlin, me)
N(prefix or number),
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)
multi-click-delay, maximum time in milliseconds between button presses to count as click2 or click3 events (Martin Blais)
edge-flip-only-when-moving(Yaron M. Minsky)
cycle-class(Kai Großjohann); can now be bound to events with more than one modifier (Timo Korvola)
uniquify-window-name; new property
unique-name. Forces the window to have a unique name
magnetism(the old method),
resistance. (Merlin, me)
define-focus-mode--make defining these things easier. Focus modes are now settable for each window individually
configure-request-hook. The new configure handler respects window gravity when resizing
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)
XCreateFontSetcauses--fall back to
custom-defaultsgiving default customization options (only if the user has no
Also, remove the need to call
.sawmillrc, it's always done now
gravity(overrides the hinted gravity value)
resize-add-edges>. Also allows twm-style resizing (Mark Probst, me)
frame-state-mutexare now functions
fp->win == 0assertion, it should be harmless and was triggering for some people
-clientIdoption from restart parameters
sawmill-defaults.jl, by calling
custom-add-required. If you have a
.sawmillrcyou'll need to do this manually
move-resize-window-todoing a combined move/resize. New variable
synthetic-configure-mutex, when set holds off sending synthetic
ConfigureNotifyevents to windows until it's unset (this is held while interactively moving or resizing windows)
after-add-window-hook. Called with a single parameter, the window that's has just been adopted
send-client-messagenow groks long integers (i.e. cons cells) in 32-bit data (Timo Korvola)
equalto compare keys, not
error-handler, implements a simple alternative error handler (and allows the much-maligned beep to be turned off), requires rep 0.11+
shade-hover, unshades windows while the pointer is over them
window-menu, shorten sticky entries as usual (James Antill)
TryExecfield in GNOME desktop files (Ian)
move-cursor, various commands for moving the mouse pointer; these commands are bound to the cursor keys when moving or resizing windows
WM_NAMEis a null text property
skip-tasklistproperties I'd stupidly broken
New or updated functions to access frame parts directly:
Other new functions:
sawmill-themerto 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
call-after-property-changedfunction can now be given a list of properties to monitor (James Antill)
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-hooknow has a second argument (apart from the window), the list of symbolic states that changed (James Antill)
skip-tasklistto the window matcher when GNOME support is enabled (Ben Liblit)
display-messagefunction update background color, and gracefully handle invalid color specifiers (Matt Krai)
window-keymap. (Matt Krai)
inactive-clicked. (Last two are new)
sawmill-themer. A GUI for creating simple themes (those without any parts defined by functions)
gnome-int, loaded by
sawmill-defaultsif GNOME is around, sets up some GNOME'ish things
make-imagenow always returns a new image
(cursor . nil)work correctly in frame definitions
Create new window instances by using the
commands. Merge instances by moving them to the same workspace, or
ungrouped. Means to put the window in a group on its own
commandpfunction when applied to autoload stubs
gnome-logoutcommand (Jens Finke)
raise-window-and-pass-through-clickcommand to pass <click2>, etc, events through to frame parts
Type=directory, but actually a file)
Grab...button to match-windows dialogue, grabs the value of an X property from a window
size, in terms of the window's size hints
popup-apps-menucommand (Gérard Milmeister)
define-frame-classwhen creating keymaps
(set ...)custom types
raise-window-and-pass-through-clickcommand to pass-through subsequent clicks
Matched Windowscustomize group
bar-windows-revariables, they're obsoleted by the general match-windows mechanism
prefix/share/sawmill/themes. Use this for system-wide themes (don't use the version specific directory)
show-messagefunction, replaced by
display-messagewith a better calling interface; also displays multi-line strings
Hypermodifier, prefix is H-
--disable-nls to disable i18n
gtkrc-call-after-changedto allow themes to receive these events (hooks are now off-limits to themes)
raise-window-and-pass-through-click; bind it to a mouse button in the
window-keymapto get the "raise window on click" behaviour that seems popular
slide-group-xfor x one of:
ignoredproperty of windows (Julian Missig)
bevel-imagefunction (Scott Sams)
gnome-menucode when GNOME binaries aren't in the first $PATH item; also accept non-alphanumeric language codes
AnyModifierand a specific button
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
gnome-share-directory, also look in
/etc/X11/applnkfor menu entries
after-framing-hook: called whenever a window's frame is changed or recalibrated
cycle-windowsonly finds a single window; also, abort immediately if there's no windows to cycle through at all
WM_NORMAL_HINTSproperty is read after it's been updated
maximize-fillfunctions to respect the
avoidproperty instead of the
maximize-avoidproperty; new functions
avoided-windows; new regexp
sawmill-client --with long inputs
WM_COMMANDhas to match
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)
set-frame-part-value--makes customizing the
_WIN_CLIENT_LISTproperty not being set properly (both missing windows immediately after they're adopted, and of intentionally skipping ignored windows)
cycle-disable-auto-raise); option to restrict cycling to the current viewport (
lock-first-workspaceis now enabled by default, and prevents both the first and last interesting workspaces being moved inwards
--with-readlineoption to configure (from Christopher P Goller firstname.lastname@example.org)
root-window-keymapis searched for key-press events
shaped-transientwindow types (make the window completely unframed)
cycle-windowscould leave a window originally under the pointer that's unfocused, drawn as though it is focused
lock-first-workspace, prevent the first workspace from being deleted when it's empty
ignore-window-input-hint, to always give windows the focus, whether they say they will accept it or not
move-window-xcommands (for x being
microGUIby Ryan Lovett email@example.com, based on the QNX Photon screenshots
Grab keybutton in the bindings widget, replaces the current binding with the next pressed key
(require 'gnome-menu)to your
~/.sawmillrcfile to load it
send-to-workspace:xfor x from 1 to 9
--prefixoption has a trailing slash
foregroundproperty of each frame part may now be an image instead of a piece of text
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...
xtermcommand to launch an xterm
Copybutton to insert a copy of the current binding
previous-workspace-rowcommands. Together with the
workspace-columnsvariable these mimic a 2d desktop
cycle-through-workspacesoption, there's now
override_redirectattribute while unmapped
override-frame-part-classesvariable--allows all frame properties to be overridden on a per-class basis
auto-window-type-alistvariable mapping window names to border types
eval-key-release-eventsto allow catching these types of keyboard events, disabled by default
meta-keysymsdescribe the virtual modifier assignments
frame-part-classesvariable). This should ensure that different themes have the same feel (but a feel that may be customized by the user)
removableproperty). Nothing makes use of this yet
--enable-cappletconfigure option to build it
gtktheme, draw bevels on window decorations
focus-proxy-clickcontrolling whether to pass the focus-inducing button-press event to the underlying window (in click-to-focus mode)
lisp/workspace.jlfor an example
auto-frame-style-alistvariable associates window name regular expressions with frame styles. Also, the
window-ops-menuhas a new submenu with all possible styles
preallocated-workspaces, the number of workspaces to create at startup
READMEfile that will be displayed in the configuration tool
~/.sawmill-custom. The old file will be moved to the new location if it exists
libexecsince it shouldn't be run manually
gradienttheme to create full-sized gradient images, trading memory for quality
customcustomize options into normal variables (they're not particularly intuitive)
rendererproperty in frame definitions. This property is a function called with args
(image state); it should draw a background into image for the specified state (
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-stylein the shell to reload the style manually
gradienttheme uses these and on-the-fly rendering to do
afterstep-like window titles
customize:groupfor each group.
theme.jlcscript 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:
select-workspace:Xfor X between 1 and 9
sawmill-client; invokes the named interactive function
window-ops-menucould be displayed from one window but then affect a different window
sloppy-focusvariable, 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)
keymapproperty of the window under the pointer, not the focused window (as with keypress events)
sawmill-clientprogram can now communicate inter-host, since it uses X properties not raw sockets
before-exit-hook, called immediately before shutting down
sawmill-uiprogram, or from the
Customize...entry in the main menu. All changes are stored in the Lisp script
simplethemes now define all four standard frame types
prefix/share/sawmill/version/lisp/themes) so that the list of all available themes can be made automatically
simpleframe style can now be customized (
sawmill-defaults.jlscript enables GNOME compliance unconditionally (since it has no ill-effects even if GNOME isn't being used)
fontattributes of each frame part may now refer to a function
First proper release
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.
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 |
Signals an error if no known color has the name name.
|get-color-rgb red green blue||Function|
|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.
Return a list of integers |
|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.
|The color used for text where no other color is defined.|
As with the color type, the font type allows X11 fonts to be manipulated by Lisp code.
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.
|Returns the name of the X11 font represented by object font (a string).|
|Returns the bounding height of glyphs in the font represented by object font.|
|text-width string &optional font||Function|
Returns the number of horizontal pixels that would be required to
display the text string using font object font (or the
value of the |
As with colors, a default font may be specified, to be used where no other font is specified.
|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.
|font-put font property value||Function|
|Associate the lisp object value with the property named by the symbol property of the font object font.|
|font-get font property||Function|
Return the value of the property named by the symbol property of
the font font, or |
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.
Creates and returns an image object containing the image defined by the
contents of the file named file-name (a string). The
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.
|A list of directory names. This defines the search path used when loading images.|
|make-sized-image width height &optional color||Function|
|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.|
|Returns a newly allocated image object, an exact copy of the image object image.|
Returns a cons-cell |
|Flip the contents of image about the vertical axis.|
|Flip the contents of image about the horizontal axis.|
|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.
|image-put image property value||Function|
|Set the property named property (a symbol) of image to value.|
|image-get image property||Function|
Return the property named property of image, or |
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.
Returns a list of integers |
The number associated with each edge of the image defines the number of pixels adjacent to that edge that will not be scaled.
|set-image-border image left right top bottom||Function|
|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.
Return the color marking transparent pixels in image, or
|set-image-shape-color image color||Function|
|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.
|image-modifier image type||Function|
Return the modifier defined by the symbol type of image, a
list of integers |
The four types are
|set-image-modifier image type gamma brightness contrast||Function|
|Set the image modifier of image defined by type.|
There are also several other functions manipulating images:
|bevel-image image border upwards &optional bevel-percent||Function|
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
|Default height of drawn bevels, as a percentage.|
|clear-image image &optional color||Function|
|Set all pixels in image to color (or black if color is undefined).|
|tile-image dest-image source-image||Function|
|Tiles source-image into dest-image, starting from the upper-left corner, working outwards.|
Cursors define the shape and hot-spot of the mouse pointer's image. A lisp type is provided for manipulating these objects.
Returns the cursor object representing the cursor defined by
data. If data is a symbol, it's replaced by its
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
|recolor-cursor cursor fg bg||Function|
|Change the colors of the cursor object cursor to fg and bg (either color objects or the names of colors).|
|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:
The glyphs associated with these names are shown in Appendix I, of Volume Two, Xlib Reference Manual.
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.
|Returns a list containing all managed window objects, in the order that they were adopted by the window manager (first to last).|
Return a window object with id xid, or |
Return a window object with name name, or |
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); 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).
|window-put window property value||Function|
|Set the lisp property named property (a symbol) associated with window object window to value.|
|window-get window property||Function|
Return the window property named property associated with the
window object window, or |
For a list of the standard window properties, see Standard Properties.
|Return the name associated with window.|
|Return the full-name associated with window. This may or may not be the same as the normal name.|
|Return the icon name associated with window.|
If window object window has a client window associated with,
return an integer defining its xid, otherwise return |
Return an integer defining the xid of the leader of the group that
window is a member of, or |
Returns a cons cell |
Returns a cons-cell |
Return an alist defining the size-hints structure specified by the
client window associated with window. Possible keys in the alist
Returns a symbol defining the current visibility of window.
Possible returned symbols are |
The input focus defines exactly which client window will receive events generated by the keyboard.
Returns the window object of the currently focused window, or
|Sets the focus to the client window associated with window.|
Defines the current method of using the mouse to assign the input
focus. Possible values are |
When in click-to-focus mode, the focus-assigning click is only passed
through to the client window if this variable is non-|
This option may be set on a per-window basis by setting the
Sawfish also maintains the order in which windows were recently focused.
|window-order &optional workspace allow-iconified all-viewports||Function|
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
|Push window object window onto the top of the focus stack.|
|Remove window object window from the focus stack.|
|Focus the most-recently-focused window on the current viewport of the current workspace.|
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
|Return a list of symbols defining the X properties set on window.|
|delete-x-property window property||Function|
|Deletes the X property named property (a symbol) associated with window.|
|get-x-property window property||Function|
Returns a list |
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
|set-x-property window property data type format||Function|
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
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:
|get-x-text-property window property||Function|
Similar to |
|set-x-text-property window property data||Function|
|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
See Standard Hooks.
The stacking order of the display defines the order in which windows are shown, from topmost to bottommost.
|Return a list of window objects defining the current stacking order of all client windows, from top-most to bottom-most.|
|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.|
|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.
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.
Similar to |
|set-window-depth window depth||Function|
|Set the stacking depth of window to depth, then restacks the windows to reflect this change.|
|stack-window-below below above||Function|
|Change stacking order of window below so that it is immediately below window above.|
|stack-window-above above below||Function|
|Change stacking order of window above so that it is immediately above window below.|
|save-stacking-order &rest forms||Macro|
Evaluate forms in an implicit |
For the following functions, when called interactively they all operate on the window that received the current event, or alternatively the currently focused window.
|Lower window to the bottom of its stacking depth.|
|Raise window to the top of its stacking depth.|
|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.|
|Decrement the stacking depth of window.|
|Increment the stacking depth of window.|
As noted above (see Window Attributes), the
window-position functions return
the current configuration of a window.
|move-window-to window x y||Function|
|Move the top-left corner of the window frame of window to (x, y).|
|resize-window-to window width height||Function|
|Set the dimensions of the client window associated with object window to (width, height).|
|move-resize-window-to window x y width height||Function|
|A combination of the previous two functions.|
|resize-window-with-hints window cols rows &optional hints||Function|
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 |
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.
|Move window interactively using the mouse. Releasing any mouse button places the window at its current position.|
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.
|Wait for the user to select a window using the mouse, then interactively move that 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:
A symbol defining the visual method of interactively moving windows.
Current options include |
A symbol defining the visual method of interactively resizing windows.
Current options include |
|When non-nil, the current window position is shown in the center of the screen.|
|When non-nil, the window size is shown in the center of the screen.|
|When non-nil, the window position is "snapped" to edges of other windows within close proximity.|
|The distance in pixels before snapping together two edges.|
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).
|Prevent object window from being displayed.|
|Ensure that window (if it has been mapped, and is within the screen boundary) is visible.|
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.
Delete window, i.e. send a |
If the application owning window supports it, send a
|Destroy window without giving the owning application any warning. window may be a window object or a numeric window id.|
|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
subsequently be invoked (see Standard Hooks).
Many window managers allow a window to be shaded; when in this state only the title bar of the window is visible.
|Arrange for only the title bar of window to be visible.|
|If the window is shaded, restore it to it's original state.|
|Toggle the shaded state of the window.|
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.
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.
|Iconify the window associated with object window.|
|Return the window associated with window from its iconified state.|
A window's iconic state may be tested through examination of its
t the window is iconified.
The dimensions of a window may be temporarily maximized.
|maximize-window window &optional direction||Command|
Maximize both dimensions of window
If defined, direction may be either
|Maximize the vertical dimension of window.|
|Maximize the horizontal dimension of window.|
|unmaximize-window window &optional direction||Command|
Restore the dimensions of window to its original, unmaximized,
If defined, direction may be either
Toggle the state of window between maximized and unmaximized.
If defined, direction may be either
|Toggle the state of window between vertically maximized and unmaximized.|
|Toggle the state of window between horizontally maximized and unmaximized.|
Sawfish provides two levels of configuration:
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.
|customize &optional group||Command|
|Invoke the user-customization GUI. group defines the class of customization variables to configure, or all classes if group is undefined.|
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
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.
|defgroup group real-name &rest keys||Macro|
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
This macro also creates an interactive function named
|defcustom variable value documentation &rest keys||Macro|
The first three arguments are analogous to the |
All other parameters are key-value pairs as with
Note that where necessary the types themselves define default
: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.
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!
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.
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).
|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:
Extra classes can be created by adding to
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
def-frame-class macro should be used to add new
classes, since it handles these situations.
|def-frame-class class alist-form &rest binding-forms ...||Macro|
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
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.
Similar to |
The following function may be used to simplify the customization of these two variables:
|set-frame-part-value class key value &optional override||Function|
Associate value with property key for all frame parts of
If override is non-nil, then the setting is installed in the
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.)
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:
bar with value
2. See Association Lists.
The attributes that may be defined are as follows:
(class . class)
(background . data)
(background . (normal focused highlighted clicked))
If an image is used it will be scaled to the size of the frame part,
tiled property is set, in which case it will be
tiled across the frame part.
(foreground . data)
(foreground . (normal focused highlighted clicked))
background attribute, by default images are not
scaled when used to define the foreground of a frame part.
(scale-foreground . value)
nil, the foreground image of the frame part will be scaled to the size of the part.
(font . font)
(font . (normal focused highlighted clicked))
(text . value)
foregroundproperty 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)
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)
x-justify, but the accepted symbols are
(renderer . function)
backgroundattribute. 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
nil(for the normal state).
(render-scale . value)
rendererproperty to be reduced by a factor of value, an integer.
(left-edge . value)
(right-edge . value)
(top-edge . value)
(bottom-edge . value)
(width . value)
(height . value)
(keymap . value)
(cursor . cursor)
get-cursorto create the required cursor object.
(removable . value)
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)
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)
nil, don't display this frame part.
The values specified for the
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).
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).
|frame-part-get window class attr||Function|
Returns the value of the attribute attr for the frame part of
class class in the current frame of window.
|set-window-frame window frame-def||Function|
|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.|
|Return the list of frame part definitions defining the frame associated with window.|
|Recreates the window frame associated with window, from the previously defined frame definition. All frame parts are reinitialized and recalibrated.|
Return a cons cell |
If window is not framed, then this function returns the same
Return a cons cell |
In order to visually differentiate between different types of windows, several predefined types of window frame exist. These types currently include the following:
transienttypes, normally just a very small title border with no text.
nil-framevariable 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
type property. It should usually be accessed
|Returns a symbol naming the frame type currently associated with window.|
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.
|add-frame-style name function||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
If no default frame style exists, the new style will be made the default.
|A symbol naming the frame style to use for windows where no other style is explicitly specified.|
|set-window-frame-style window style &optional type from-user||Function|
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).
|set-frame-for-window window &optional force type||Function|
If window has no frame style associated with it, then chooses the
default value for this window, the value of |
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.
|Forcibly reselect all window frame styles. Only windows with a user specified style are not changed to the current defaults.|
|Completely recreate all window frames that are defined by the style style.|
Several window properties are used while choosing frame styles:
The user-chosen frame style of the window, or |
|The current frame style of the window.|
|When set, the window is not given a frame.|
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.
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.jlc. This script
will be evaluated, it should provide a frame style of the same name as
the theme (by calling
While the theme script is evaluating the
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
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
would actually be called
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
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
SIGINT signal may unblock it. Hopefully themes are unable to
affect the rest of the user's environment, but there are no
|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.|
The name of the user's theme directory, by default
|The name of the system theme directory.|
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
removable property, Frame Part Definition).
|remove-frame-class window class||Function|
|Disable all frame parts that are a member of class in window where possible.|
|add-frame-class window class||Function|
|Enable all frame parts that are a member of class in window.|
XXX what do I want to say here?
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) (
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 &")))
system function simply executes its single argument using
|Displays a menu defined by the list of item definitions spec.|
|Display the menu listing all window operations.|
|Display the main menu.|
|Displau the applications menu.|
|Contains the root menu definition.|
|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.
This variable defines if, and for how long, the menu subprocess is
allowed to remain executing for after the last menu has completed. If
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.
This function returns |
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:
Note that the
A modifiers are virtual modifiers
assigned dynamically, according to the X server's
A virtual modifier is assigned to the X
modifier with either the <Alt_L> or <Alt_R> keysym assigned to
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:
Also, there are several pseudo-keys for describing mouse events:
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.
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)
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:
A list defining the names of the X keysyms generating the virtual
A list defining the names of the X keysyms generating the virtual
A list defining the names of the X keysyms generating the virtual
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
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
call-command function that the function definition may
be called interactively. The second element of the declaration form
interactive symbol) defines how the argument values
applied to the command are computed.
The structure of an interactive declaration, then, is:
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,
nilor 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.
The currently available prefixes are,
nilif no window is focused.
current-event-windowfunction, or if this returns
root, the currently focused window.
A null line produces an argument value of
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.
This function returns |
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.
|call-command command &optional prefix-arg||Function|
This function calls the command command interactively. See the
documentation of |
If the prefix-argument is non-nil it defines the value of the
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
|Returns a newly-created empty keymap.|
|bind-keys keymap &rest bindings||Function|
Installs zero or more key bindings into the keymap keymap, then
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
(bind-keys keymap "C-f" 'foo "C-b" 'bar)
|unbind-keys keymap &rest keys||Function|
|Removes the bindings of the events keys (these may be the names of the events or the event objects themselves) from the keymap keymap.|
|search-keymap event keymap||Function|
Search for a binding of the event event in keymap. If a
binding is found a cons cell |
There are several pre-defined keymaps that are always available:
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
The active keymaps are determined as follows:
override-keymapis non-nil, then this is the only keymap searched
keymapproperty of the currently "clicked" frame part if there is one,
keymapproperty of the currently focused window
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
hook--the first function that returns non-nil will terminate the hook
Perform the usual binding lookup for the event object object.
Returns the command found, or |
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:
|When non-nil, key events bound to modifier keys are evaluated.|
|When non-nil, key-release events are evaluated.|
While a command is being evaluated, information about the event that caused it may be found:
|Return the event which caused the current command to be invoked|
|Returns the string which the current event would usually insert.|
Return the window that received the current event, or the symbol
|Return the previous event which occurred.|
|proxy-current-event window &optional mask propagate||Function|
Send the current X event to window, either a window object, a
numeric window id, or the symbol |
mask may be an integer defining the X event mask to pass to the
This is a wrapper for the |
Events that have to be grabbed to be received (i.e. all bindings in the
This is normally not important, but if the command expects to receive
further events it must call
|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.|
|accept-x-input &optional mask||Function|
|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).|
|Returns the number of X events waiting to be handled.|
|query-pointer &optional from-server||Function|
Returns a cons cell |
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).
Returns the top-level window under the mouse pointer, or |
Returns a cons cell |
|warp-cursor x y||Function|
|Move the mouse pointer to position (x, y) relative to the origin of the root window.|
|warp-cursor-to-window window &optional x y||Function|
Move the mouse pointer to position (x, y) relative to the
client window associated with object window.
If x and y are
|Prevent any other clients from accessing the X server.|
After a call to |
Note that calls to
|with-server-grabbed &rest forms||Macro|
|Evaluate forms with the server grabbed. Releases the grab afterwards.|
|grab-pointer &optional window cursor||Function|
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
|Release the grab on the mouse pointer.|
|grab-keyboard &optional window||Function|
Grab the keyboard and direct all keyboard events to window object
window. If window is |
Returns non-nil if the grab succeeded.
|Release the grab on the keyboard.|
|Return the width of the root window.|
|Return the height of the root window.|
|draw-window-outline mode x y width height||Function|
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
|erase-window-outline mode x y width height||Function|
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
|display-message &optional text attributes||Function|
Display the string text in a window on the screen. If text
attributes is an alist specifying how the string should be
displayed; each element of the list is a cons cell
Possible attributes currently include:
gradient feature allows color gradients to be drawn in
(require 'gradient) to load this feature.)
|draw-vertical-gradient image from to||Function|
|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.|
|draw-horizontal-gradient image from to||Function|
|Draw a horizontal color gradient in image, from left to right.|
|draw-diagonal-gradient image from to||Function|
|Draw a horizontal color gradient in image, from the top-left corner to the bottom-right.|
|Flush all pending X requests, don't wait for them to finish.|
|send-client-message window type data format||Function|
Send an X |
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).
|create-window parent x y width height||Function|
Create an unmapped window that is a child of parent (a window
object, an integer window id, or the symbol |
Returns the window id of the new window.
|Return the integer identifying the X atom with the same name as symbol.|
|Return the symbol with the same name as the X atom identified by the integer integer.|
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.
As well as using the standard
call-hook function, sawfish also
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.
|call-window-hook hook window &optional args hook-type||Function|
Call hook for window with further arguments args. See
The following table describes all standard hooks called by Sawfish, and the arguments they are called with:
before-add-window-hookis called first, it should only set properties of the window.
(window alist)when an X
ConfigureRequestevent is received. alist may include items
(stack . above),
(stack . below),
(position . coordinates),
(dimensions . dimensions).
(window atom-name type)where type is
ortype hook. Called with arguments
(window type data-array).
ortype hook. Called the first a window is mapped.
gtkrcmodule to load the current gtk style parameters, this hook is called when the style changes.
bottomdefining the edge in question.
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.
nil. See Frame Types.
place-window-hookis only called when this is unset.
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:
|sm-add-saved-properties &rest properties||Function|
|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
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:
|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.)|
List of functions called when the state of a window is restored. Each
is called with arguments |
Each function should look for the properties it saved, and then take any action dependent on the values.
The following hook is also called.
|Hook called after loading a saved session.|
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
~/.sawmill directory will automatically be renamed
~/.sawfish unless it would overwrite an existing file. Both
~/.sawmillrc will be checked currently
(though only one will be actually loaded).
My apologies for any inconvenience caused.
Well I had to choose something! And hopefully it satisfies the main requirements:
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 firstname.lastname@example.org
There are several files controlling this:
This file is loaded after
sawmill-defaults, but before
.sawfishrc, now things have changed?
~/.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
.sawfishrc file if you want to start with all
the standard features loaded.
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
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)
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.
Bind the event Button1-Click1 in the
window-keymap to the
Popup Menus node in the Info manual (see Popup Menus)
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
Window Frames node of the Info manual (see Window Frames)
Basically though, create a directory
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
Recent versions of sawfish include a program
allows simple themes to be created using a GTK+ interface. Ian McKellar
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 <
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
themes/brushed-metal directory for an example, and the
Info manual for the documentation
Thanks to those nice people at themes.org, there's now
http://sawmill.themes.org/> for your theming pleasure
There was a problem with older versions of the
package preventing engine based themes working with several interpreted
languages. Get the latest
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
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
No. This can easily be done by a separate application (e.g. with the
GNOME hints, simply monitor property
_WIN_WORKSPACE on the root
Yes, thanks to Erik Arneson email@example.com who manages it.
To subscribe, send a message to firstname.lastname@example.org with
subscribe sawmill in the body.
The list is archived at <
From Ryan Pavlik email@example.com:
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.
Sawfish works stably on Solaris, but you may need to do two things:
imlib_config, the MIT-SHM option is on the
--disable-ximoption to configure
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
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!)
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.
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.
accept-x-input: Event Loop
add-frame-class: Removing Frame Parts
add-frame-style: Frame Styles
allow-events: Event Loop
call-window-hook: Standard Hooks
check-frame-availability: Frame Styles
create-window: Other Functions
current-event: Event Loop
current-event-string: Event Loop
current-event-window: Event Loop
def-frame-class: Frame Part Classes
delete-window: Destroying Windows
delete-window-safely: Destroying Windows
delete-x-property: X Properties
destroy-window: Destroying Windows
display-message: Display Functions
draw-diagonal-gradient: Gradient Functions
draw-horizontal-gradient: Gradient Functions
draw-vertical-gradient: Gradient Functions
draw-window-outline: Display Functions
erase-window-outline: Display Functions
forget-button-press: Event Loop
frame-part-get: Frame Part Definition
get-x-property: X Properties
get-x-text-property: X Properties
grab-keyboard: Grab Functions
grab-pointer: Grab Functions
grab-server: Grab Functions
hide-window: Showing and Hiding Windows
iconify-window: Iconifying Windows
input-focus: Input Focus
last-event: Event Loop
list-x-properties: X Properties
lookup-event-binding: Event Loop
lower-window: Window Stacking
lower-window-depth: Window Stacking
maximize-window: Maximizing Windows
maximize-window-horizontally: Maximizing Windows
maximize-window-horizontally-toggle: Maximizing Windows
maximize-window-toggle: Maximizing Windows
maximize-window-vertically: Maximizing Windows
maximize-window-vertically-toggle: Maximizing Windows
move-resize-window-to: Moving and Resizing Windows
move-selected-window: Moving and Resizing Windows
move-window-interactively: Moving and Resizing Windows
move-window-to: Moving and Resizing Windows
popup-apps-menu: Popup Menus
popup-menu: Popup Menus
popup-root-menu: Popup Menus
popup-window-menu: Popup Menus
proxy-current-event: Event Loop
query-last-pointer: Pointer Functions
query-pointer: Pointer Functions
query-pointer-window: Pointer Functions
raise-lower-window: Window Stacking
raise-window: Window Stacking
raise-window-depth: Window Stacking
rebuild-frame: Frame Functions
rebuild-frames-with-style: Frame Styles
reframe-all-windows: Frame Styles
reframe-windows-with-style: Frame Styles
remove-frame-class: Removing Frame Parts
resize-selected-window: Moving and Resizing Windows
resize-window-interactively: Moving and Resizing Windows
resize-window-to: Moving and Resizing Windows
resize-window-with-hints: Moving and Resizing Windows
restack-windows: Window Stacking
save-stacking-order: Window Stacking
screen-height: Display Functions
screen-width: Display Functions
send-client-message: Other Functions
server-grabbed-p: Grab Functions
set-frame-for-window: Frame Styles
set-frame-part-value: Frame Part Classes
set-input-focus: Input Focus
set-window-depth: Window Stacking
set-window-frame: Frame Functions
set-window-frame-style: Frame Styles
set-x-property: X Properties
set-x-text-property: X Properties
shade-window: Shading Windows
show-window: Showing and Hiding Windows
sm-add-saved-properties: Session Management
stack-window-above: Window Stacking
stack-window-below: Window Stacking
stacking-order: Window Stacking
stacking-order-by-depth: Window Stacking
sync-server: Other Functions
toggle-window-shaded: Shading Windows
ungrab-keyboard: Grab Functions
ungrab-pointer: Grab Functions
ungrab-server: Grab Functions
uniconify-window: Iconifying Windows
unmaximize-window: Maximizing Windows
unshade-window: Shading Windows
warp-cursor: Pointer Functions
warp-cursor-to-window: Pointer Functions
window-dimensions: Window Attributes
window-frame: Frame Functions
window-frame-dimensions: Frame Functions
window-frame-offset: Frame Functions
window-framed-p: Frame Functions
window-full-name: Window Attributes
window-get: Window Property Lists
window-group-id: Window Attributes
window-icon-name: Window Attributes
window-id: Window Attributes
window-mapped-p: Window Attributes
window-maximized-horizontally-p: Maximizing Windows
window-maximized-p: Maximizing Windows
window-maximized-vertically-p: Maximizing Windows
window-name: Window Attributes
window-on-top-p: Window Stacking
window-order: Input Focus
window-order-focus-most-recent: Input Focus
window-order-pop: Input Focus
window-order-push: Input Focus
window-position: Window Attributes
window-put: Window Property Lists
window-shaped-p: Window Attributes
window-size-hints: Window Attributes
window-transient-p: Window Attributes
window-type: Frame Types
window-visibility: Window Attributes
window-visible-p: Showing and Hiding Windows
window-wants-input-p: Window Attributes
with-server-grabbed: Grab Functions
x-atom: Other Functions
x-atom-name: Other Functions
x-events-queued: Event Loop
x-kill-client: Destroying Windows
x-raise-window: Window Stacking
add-to-workspace-hook: Standard Hooks
add-window-hook: Standard Hooks
after-initialization-hook: Standard Hooks
after-move-hook: Standard Hooks
after-resize-hook: Standard Hooks
apps-menu: Popup Menus
avoid: Standard Properties
before-add-window-hook: Standard Hooks
before-exit-hook: Standard Hooks
before-move-hook: Standard Hooks
before-resize-hook: Standard Hooks
client-message-hook: Standard Hooks
client-set-position: Standard Properties
configure-request-hook: Standard Hooks
current-frame-style: Standard Properties, Frame Styles
default-frame-style: Frame Styles
depth: Standard Properties
destroy-notify-hook: Standard Hooks
enter-flipper-hook: Standard Hooks
enter-frame-part-hook: Standard Hooks
enter-notify-hook: Standard Hooks
enter-workspace-hook: Standard Hooks
eval-key-release-events: Event Loop
eval-modifier-events: Event Loop
fixed-position: Standard Properties
focus-click-through: Standard Properties
focus-in-hook: Standard Hooks
focus-mode: Input Focus
focus-out-hook: Standard Hooks
focus-proxy-click: Input Focus
focus-when-mapped: Standard Properties
frame-part-classes: Frame Part Classes
frame-style: Frame Styles, Standard Properties
gravity: Standard Properties
gtkrc-changed-hook: Standard Hooks
hide-client: Standard Properties
iconified: Standard Properties
iconify-window-hook: Standard Hooks
ignore-program-position: Standard Properties
ignore-window-input-hint: Standard Properties
ignored: Standard Properties, Frame Styles
keymap: Standard Properties
leave-flipper-hook: Standard Hooks
leave-frame-part-hook: Standard Hooks
leave-notify-hook: Standard Hooks
leave-workspace-hook: Standard Hooks
map-notify-hook: Standard Hooks
menu-program-stays-running: Popup Menus
move-outline-mode: Moving and Resizing Windows
move-show-position: Moving and Resizing Windows
move-snap-edges: Moving and Resizing Windows
move-snap-epsilon: Moving and Resizing Windows
never-focus: Standard Properties
override-frame-part-classes: Frame Part Classes
place-mode: Standard Properties
place-window-hook: Standard Hooks
placed: Standard Properties
placement-weight: Standard Properties
post-command-hook: Standard Hooks
pre-command-hook: Standard Hooks
property-notify-hook: Standard Hooks
remove-from-workspace-hook: Standard Hooks
removed-classes: Standard Properties
reparent-notify-hook: Standard Hooks
resize-outline-mode: Moving and Resizing Windows
resize-show-position: Moving and Resizing Windows
root-menu: Popup Menus
shade-window-hook: Standard Hooks
shaded: Standard Properties
shape-notify-hook: Standard Hooks
sm-after-restore-hook: Standard Hooks, Session Management
sm-restore-window-hook: Session Management, Standard Hooks
sm-window-save-functions: Session Management, Standard Hooks
sticky: Standard Properties
sticky-viewport: Standard Properties
type: Standard Properties
unbound-key-hook: Standard Hooks
uniconify-window-hook: Standard Hooks
unmap-notify-hook: Standard Hooks
unshade-window-hook: Standard Hooks
viewport-moved-hook: Standard Hooks
viewport-resized-hook: Standard Hooks
visibility-notify-hook: Standard Hooks
while-moving-hook: Standard Hooks
while-resizing-hook: Standard Hooks
window-depth-change-hook: Standard Hooks
window-maximized-hook: Standard Hooks
window-moved-hook: Standard Hooks
window-resized-hook: Standard Hooks
window-state-change-hook: Standard Hooks
window-unmaximized-hook: Standard Hooks
workspace-state-change-hook: Standard Hooks
workspaces: Standard Properties