You're encouraged to record even the tiniest tips here!

If you have any questions, you can write it in Your voice page, but the response will be faster to ask in the Mailing list.

Contents classification[]

Usage & Howto[]

See also scripts and snippets.


See also Snippets#Little function to aid debugging


See also the debugging items above.


Project Maintenance[]

How to make two-stroke key binding[]

You can make two-stroke (or more) key binding.

For example, to make Hyper-e e run emacs,

(define my-emacs-keymap (make-keymap))
(bind-keys global-keymap "H-e" my-emacs-keymap)
(bind-keys my-emacs-keymap
           "E" '(run-shell-command "emacsclient -c")
           "e" '(run-shell-command "urxvt -e emacsclient -t")
           "r" '(run-shell-command "emacsclient -e '(make-remember-frame)'")
           "g" '(gimme-exact-name "Gnus")
           "w" '(gimme-exact-name "w3m"))

(Gimme is a user-contributed script.) More nesting also works. Thanks to Jose A. Ortega Ruiz and Jason Dunsmore.

I have three xterms. How can I set viewport for each?[]

Pass -name any-name-here arguments for each. Then using 'class' from the configurator -> window rules (former "Matched window"), you can set options for each. The default class is Xterm/xterm, but with -name, it will be Xterm/any-name-here.

If it's the viewport $ xterm -geometry +0+2000
does the job, too, but the coordinate is relative to the current one. So this is useful for xinitrc or .Xclients.

Starting from Sawfish 1.6, you can also use the new `new-viewport' window-matcher to achieve this:

( add-window-matcher 'WM_CLASS "^XTerm/xterm$"
  '( new-viewport . t ) )

How to search lisp functions & variables[]

Obtain the source, and use search tools described below:

Note that in rep, these three definitons exist:

  • (define (func-name args...) ,
  • (defun func-name (args...) ,
  • Sfunc_name (in C files. Note that underscore _ is used.)

Don't forget to search in librep, too.


Ack is something like 'find + grep', written in perl. In Debian, it is renamed to 'ack-grep'.

Quickstart: Prepare ~/.ackrc. An example:

# define 'rep type'; this is something like an alias to *.jl
# use less by default and set its options
--pager=less -R -M --shift 5 -i
# always color

Sample session:

$ cd sawfish-1.3.4
$ ack "max-height"

Output; matched parts get highlighted:

src/windows.c:55:DEFSYM(max_height, "max-height");
src/windows.c:1253:`max-height', `min-width', `max-width', `height-inc', `width-inc',
lisp/sawfish/wm/commands/size-window.jl:54:        (y-max (cdr (assq 'max-height hints)))
lisp/sawfish/wm/windows.jl:259:                               'max-width 'max-height) hints)) 65535))
lisp/sawfish/wm/state/maximize.jl:275:      (max-height (cdr (assq 'max-height hints)))

Note that the search is recursive. If you want to exclude C files, then either of these do the job:

  • $ ack --nocc "max-height" - by disabling 'cc' files. Or --norep ignores *.jl files, as defined in ~/.ackrc
  • $ ack "max-height" lisp/ - by specifying directories.

By default, *.jlc files are ignored.


If you have git repository,
$ git grep "max-height" lisp/
does almost the same as ack. It's much faster than ack.

Latest source is preferred over old byte-compiled file[]

In librep/sawfish, the latest source *.jl file is used, instead of the not-updated byte-compiled *.jlc files, unlike emacs. This is extremely useful in testing.

Output debugging info[]


(format standard-error "last-command: \"%s\"\n" last-command)

To use this technique for sawfish-config (former sawfish-ui), the GUI configurator, remember that stdout and stderr are redirected to /dev/null in wm/customize.jl.

From Sawfish-1.6.0, output of sawfish-config (renamed from sawfish-ui) can be redirected with customize-redirect variable.

Nested X Server[]

Sometimes it is interesting to run X11 programs inside a different X server. This can be done via tools like Xnest or Xephyr. If you want you can use a different user account so you can run completly different configurations for the processes running inside the virtual servers.

IMPORTANT TODO: look if it is possible (and how) to get Xinerama or similar things.

Sawfish tries to load files under $HOME/.sawfish/, so you may want to set $HOME to some different value when using Xnest or Xephyr.

Bug and workaround in nested X server[]

When you try to quit Sawfish inside of nested X, then sometimes the Sawfish in the host X server is killed. It can be prevented, by explicitly calling

sawfish-client --display :1 -e '(quit)'


Xnest is an old server, that runs as a window of another. It is the part of X. Simplest thing is to run it as DISPLAY :2 and without access checks.

$ Xnest -ac :2
$ export DISPLAY=:2
$ sawfish

You can try with a more complex version, one that sets root window to black, loads xauth info (created with first command), uses two "monitors" of 400*300 (you will get :2.0 and :2.1), disables keyboard extension (this helps if the layout is non US) and then launches different programs, making sure sawfish handles all the screens.

$ echo localhost > ~/.xauth
$ Xnest -br -auth ~/.xauth -scrns 2 -geometry 400x300 -kb :2
$ export DISPLAY=:2
$ sawfish --multihead &
$ export DISPLAY=:2.0
$ xterm &
$ export DISPLAY=:2.1
$ xeyes &


(Jan 2010) Xephyr is newer than Xnest, but when your host server uses evdev for keyboard layout, then it doesn't work, since Xephyr uses xkb and the mapping gets mixed up. [1]

Xephyr is similar to Xnest in what it does, but it has a newer code base and supports some modern X extensions (even if host server doesn't) such as Composite, Damage, RandR. For the best possible performance it uses SHM images and updates the shadow framebuffer via the Damage extension. It also has a visual debugging mode for observing screen updates.

Notice the size parameter is different.

$ Xephyr -ac -screen 800x600 :2
$ export DISPLAY=:2
$ sawfish

How to debug crashes under debian[]

A way to debug sawfish crashes under debian is described here, and more details here.

Getting info on windows[]

You can use xwininfo or xprop to obtain information on windows. The first gives mostly geometry info and some states, the later lists the window properties (WM_*, _NET_*, _WIN_* etc) and can be very verbose sometimes (_NET_WM_ICON tends to be huge, eg).

To list all windows whilst cutting out the bulk of the noise, try

xwininfo -root -tree | egrep -v 'child(ren)?:|\(has no name\)'

Another thing to look up is xrdb for classic X11 apps. xrdb -query lists current data in the X resource database, like default sizes, positions, colours or states.

Basic Window Snooper is a lisp script which provides similar function.

Insert here where to look for info about common toolkit configs.

How can I learn rep? How does it differ from other lisps?[]

See here.

Info file compilation[]

Info file can be compiled without running configure with:

$ makeinfo  -I . sawfish.texi -o

Emacs bug in highlight & syntax parsing?[]


(add-hook 'sawfish-mode-hook
	  (lambda ()
	    (set (make-local-variable
		  'open-paren-in-column-0-is-defun-start) nil)

in .emacs.el, if you exprerience highlight and syntax analysis bug in sawfish mode. (This may be useful for other lisp modes, too.)

Actually, this is not a bug. Emacs assumes the oper paren '(' in the first column as a beginning of the defun for speed hack.

sawfish-client usage[]

Auto-loading functions for sawfish-client[]

If you often call your own set of functions from sawfish-client, then define them in ~/.sawfish/rc, or my-tools module and put (require 'my-tools) in ~/.sawfish/rc. Then you can access them without 'require'. This applies to 'sawfish-mode' in emacs, too.

It's because both ~/.sawfish/rc and sawfish-client reside in user structure.


  • open / require in 'my-tools' module does not affect sawfish-config. You have to do 'require' for every module you want.
  • Some functions, for example those in are already available without this trick.

Exit from sawfish-client[]

  • Add -e option to make it output error messages.
  • You can exit from sawfish-client by pressing C-d.

Starting from Sawfish 1.6, you can use ,quit to exit from sawfish-client

  • Note that C-c kills the Client AND the Window Manager!

How to manage customization files[]

Each has their own taste, so here're examples.

  • Put customization files under version control system, like git, svn, etc.
  • Break up things into files, and make .sawfish/rc be a collection of requires.
  • Byte compilation can reveal some syntax errors.

Invoking Sawfish from a wrapper script[]

Invoking sawfish from a wrapper script is sometimes a good idea. See [2] and [3].

Signal during initialization breaks sawfish[]

A signal sent by (signal 'error-symbol data) during the initialization breaks the sawfish process.

Patches in mail archive[]

Note that in the web interfarce of the mailing list archive, some @ signs are not displayed. (It should be. Think of -> foo bar net.) This can be problematic for texinfo files. Use the original message in your mua or download the gzipped text.

Sawfish and xdg-open[]

xdg-open is a generic way of letting an "unspecified" application open a given file, eg: xdg-open $HOME may open $HOME in any software which is setup to open inode/directory (or x-directory/normal) mime-types. Unfurtionally another `open' is needed, either kfmclient (KDE), exo-open (XFCE) or gnome-open (GNOME), sawfish doesn't have one, therefore xdg-open is only a minimalistic stub when using sawfish standalone. Next follows how to make xdg-open use gnome-open (may be changed to kfmclient/exo-open, of course) instead:

In your resource put:

Note: starting with Sawfish 1.10 you don't need this step anymore - Sawfish now propagtes this property on startup.

(set-x-text-property 'root 'WINDOW_MANAGER (vector "sawfish"))

next make xdg-open WINDOW_MANAGER property aware, open /usr/bin/xdg-open go to detectDE() function and add the 3rd elif below:

# Checks for known desktop environments
# set variable DE to the desktop environments name, lowercase

    if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde;
    elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome;
    elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce;
    # add the line below
    elif xprop -root WINDOW_MANAGER | grep ' = \"sawfish\"' >/dev/null 2>&1; then DE=gnome; 

to change the default applications, issue xdg-mime, as an example we'll let nautilus open directories:

as root:
xdg-mime default nautilus-folder-handler.desktop inode/directory

arguement 2 must be a valid .desktop in either /usr/share/applications or $HOME/.local/share/applications arguement 3 must be a valid mimetype

Sawfish and some of docks application[]

If you are using some dock applications (e.g. wbar, CairoDock, Plant etc) and you faced with problem of maximize any window in SawFish: dock application reserved some boud of screen to it needs when it's not visible.

To resolve it need to specify that dock window shouldn't include during calculation of reserved bouds of the screen. You can specify this in two ways:

1. Using Window Rules Configuration UI:

Screenshot from 2013-03-19 13-26-49

2. Use configuration is .sawfishrc:

(add-window-matcher '((WM_CLASS . "^Plank/plank$"))
     (avoid . #f)

Also in the first and the second case you can specify another options for this dock(window). E.g. depth to have above some of another windows.

Compiler cache and so on[]

'ccache' is a C compiler cache. If you compile almost same sources repeatedly, then it's handy.

There're utilities to color outputs of compilers, like 'colorgcc' and 'colormake'.

Sawfish freezes when I try wrong code with sawfish-client[]

There're several workarounds:

  • Prepare a background program which kills Sawfish when it detects a usb flash memory you don't use often.
  • Run Sawfish inside of nested X server.
  • You can switch to virtual console (alt+ctrl+f1), login and do "killall sawfish".
      - Really? It doesn't work for me, e.g. when you do $ sawfish-client -e "(while t)". - Teika kazura 04:32, April 17, 2010 (UTC)