Features of SCWM
SCWM has several features that few other window managers support. In this section, I will describe some of the things SCWM can do for you, if you decide make it your window manager.
Graphical Configuration
Although SCWM is fully programmable, novice users will prefer a simple graphical interface to customization. SCWM provides developers with a simple, declarative language to specify what options are configurable, and then it automatically generates a Preferences GUI. (This feature is similar to the Customization capabilities of recent versions of Emacs and XEmacs).
Thus, we can specify a new *highlight-foreground* option simply using the following Scheme declaration:
(define-scwm-option *highlight-foreground* "white" "The foreground (text) color for the titlebar of the window with the keyboard focus." #:type 'color #:group 'face #:setter (lambda (v) (set-highlight-foreground! v)) #:getter (lambda () (highlight-foreground)))
SCWM's preferences module combines that specification with all of the others to create the dialog box shown in Figure 1.
Figure 1. Options dialog box
Flashing Windows Upon Errors
Have you ever started to build a program using make in one XTerm and then gone to read email while that process was running? Have you ever been disappointed after 15 minutes of reading email because you discovered that a silly typo caused that build to fail immediately? With SCWM and Zsh, I've configured my environment to ring a bell and make the XTerm blink when an error is encountered, thus alerting me that the XTerm might need attention. Here's how to do it.
First, I make Zsh's error function print a special escape sequence, which recent versions of XTerm (and several other X/11 terminal emulators) recognize as a request to set an X property on its top-level window:
function TRAPZERR () { print -u2n "\033]3;alert=true\a" }
After receiving that control sequence, XTerm associates the X property alert with the value true on its main window. At this point, SCWM becomes involved because its X-property-notify-hook procedures are invoked. A callback procedure that is attached to that hook is passed the X property object and the window that has that property. It can then use the X-property-get primitive to determine that alert now has the value true and can call flash-window on the passed-in window object (see property-respond.scm and flash-window.scm).
Replacing Fully Obscured Windows
Have you ever been confused because you couldn’t find a window that was completely hidden by another window, that appearing above that lost window? SCWM helps you to avoid this situation by using its window-fully-obscured-hook. We can define a handler procedure like so:
(define (fully-obscured-handler win from-vport-move?) (if (not from-vport-move?) (clever-place-window win)))
Then we can tell SCWM to use that handler procedure whenever a window becomes fully obscured:
(add-hook! window-fully-obscured-hook fully-obscured-handler)
To try this out, first start a bunch of XLogo windows. Then, bring a large XTerm or Emacs window to the front of the stacking order, and move it around over top of the XLogo windows. Each of the XLogo windows will get replaced when they would otherwise have become hidden. You could also choose to iconify those windows or pick a different placement procedure (instead of the ordinary clever-place-window procedure, which is the one that is often used to initially place a window on screen).
Finding a Lost Window
If you're like many users, you might just start a new XTerm when you cannot find a specific XTerm window. Alternatively, you might search a menu that contains all of the windows that are currently available. Unfortunately, that list can grow very long and can therefore complicate finding the window you want. SCWM provides a couple of alternatives to these undesirable methods.
Because SCWM menus are fully programmable, you can arrange the menus however you wish. In particular, the standard system configuration binds a click of the middle mouse button on the root (background) window to execute show-window-list-by-resource-with-geometry. This procedure pops up a window list with windows that are grouped according to their window resource. All XTerm windows are a single submenu, all Netscape windows are their own submenu, and so on. In addition, as you move your pointer over the menu, the corresponding window is highlighted both onscreen and in the FVWM2 pager (if you have it running), so you can tell to which window each item refers.
Searching for windows that match a string is another capability that SCWM provides:
(bind-key 'all "C-A-S-m" show-window-list-matching-interactively)
The Control+Alt+Shift+m keystroke (in any context) is bound to a procedure that prompts you for a string, which it then uses to find windows that contain that substring in their title. For example, if you enter Xdvi, a menu will pop up listing windows named Xdvi as well as all other windows that contain those four characters anywhere in their titles. This feature makes it much easier to find a specific window, and it is especially useful if you want your Emacs and XTerm windows' titles to change based on the file they are editing or the command they are executing.
Integration with Netscape
One of my most frequent daily activities is visiting a URL that exists in an email message, a text file, or a command output. Although many mail readers support talking to your Netscape process, there are always occasions when users are stuck copying and pasting (or even retyping) a URL from one place onscreen into a Netscape: Open Page dialog box. Again, SCWM provides a better alternative. By default, the keystroke Control+Shift+Meta+t is bound to the procedure netscape-goto-selection-url (from netscape.scm):
(define*-public (netscape-goto-selection-url #&optional (new *netscape-new-window*) (selection "PRIMARY")) "Goto the url that is held in the X11 selection, SELECTION. Uses the cut buffer instead if no selection exists. See `X-handle-selection-string' and `netscape-goto-url'. NEW can be #f to not open a new netscape frame. SELECTION defaults to \"PRIMARY\" if not given." (interactive) (X-handle-selection-string selection (lambda (str) (netscape-goto-url (if str str (X-cut-buffer-string)) display-message-briefly new))))
This procedure uses the Netscape remote-control protocol to make a Netscape browser window display the currently selected text string. Thus, you can simply highlight a URL using your mouse, and then press Control+Shift+Meta+t to instruct Netscape to instantly visit that site.
Similarly, I often do a Google search for a text string that is in an Emacs buffer or an email message. With SCWM, I highlight the keywords and then press Alt+s, which is bound to netscape-google-search-selection-url. That procedure queries the Google search engine for the current X/11 text selection.
Using Registers to Control Focus
I often alternate my work between two or more windows. Although SCWM supports Alt+Tab window focus switching (much like MS-Windows), it also provides registers that can help make the task even easier. Hyper+f (Hyper is another, less frequently used modifier key which not all keyboards have; a different key-binding can obviously be substituted) is bound to focus-to-register, and Hyper+g is bound to jump-to-register. These two commands enable you to save the currently focused window to an arbitrary key, and then later switch focus back to that window.
For example, if I'm actively working in both an XEmacs window and an XTerm window, I can name the XEmacs window "A" by focusing it (by moving my mouse pointer into that window, assuming mouse-focus mode) and then pressing Hyper+f, releasing those keys, and pressing the (unshifted) "a" key. I can then focus on the XTerm window and press Hyper+f, followed by the "B" key. Now the "A" register remembers that the focus should be on the XEmacs window, while the "B" register contains the notion that the focus should be on the XTerm window. More importantly, you can use Hyper+g to go to (that is, jump to) a register. If you press Hyper+g and then the "A" key, the XEmacs window will get the focus; if you press Hyper+g and then the "B" key, the Xterm will get the focus.
Window configurations, global window arrangements, and sets of selected windows can also be saved into registers using Hyper+c, Hyper+x, and Hyper+t, respectively. In each case, Hyper+g is used to return to the saved information stored in the chosen register.