commit e1ea2479946206babdea6cc157285e5cbd0e7703
parent 68b77ab4e8e55214a4e71626e94e0a126fe23d41
Author: Kris Maglione <kris@suckless.org>
Date: Sun, 27 Jun 2010 17:08:20 -0400
[guide] Split guide sections into separate .tex files.
Diffstat:
doc/customizing.tex | | | 943 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
doc/gettingstarted.tex | | | 294 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
doc/introduction.tex | | | 166 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
doc/license.tex | | | 29 | +++++++++++++++++++++++++++++ |
doc/wmii.tex | | | 1506 | +++---------------------------------------------------------------------------- |
5 files changed, 1481 insertions(+), 1457 deletions(-)
diff --git a/doc/customizing.tex b/doc/customizing.tex
@@ -0,0 +1,943 @@
+\chapter{Customizing \wmii}
+
+There are several configuration schemes available for \wmii. If
+you're only looking to add basic key bindings, status monitors,
+\emph{et cetera}, you should have no trouble modifying the stock
+configuration for your language of choice. If you're looking for
+deeper knowledge of \wmii's control interface though, this
+section is for you. We'll proceed by building a configuration
+script in \POSIX\ |sh| syntax and then move on to a discussion
+of the higher level constructs in the stock configuration
+scripts.
+
+For the purposes of pedagogy, we'll construct the script in the
+literate programming style of Knuth, whereby we construct the
+code in fragments and explain each one in detail. For your
+convenience, each fragment name is linked to its definition.
+
+\section{Events}
+
+The \wmii\ control interface is largely event driven. Each event
+is represented by a single, plain-text line written to the
+|/event| file. You can think of this file as a named pipe. When
+reading it, you won't receive an EOF\footnote{End of File} until
+\wmii\ exits. Moreover, any lines written to the file will be
+transmitted to everyone currently reading from it. Notable
+events include key presses, the creation and destruction of
+windows, and changes of focus and views.
+
+We'll start building our configuration with an event processing
+framework:
+
+\begin{Fragment}{Event Loop}
+ # Broadcast a custom event
+ wmiir xwrite /event Start wmiirc
+
+ # Turn off globbing
+ set -f
+ # Open /event for reading
+ wmiir read /event |
+ # Read the events line by line
+ while read line; do
+ # Split the line into words, store in $@
+ set -- $line
+ event=$1; shift
+ line = "$(echo $line | sed ‘s/^[^ ]* //’ | tr -d ‘\n’)"
+ # Process the event
+ case $event in
+ Start) # Quit when a new instance starts
+ [ $1 = wmiirc ] && exit;;
+ «Event Handlers»
+ esac
+ done
+\end{Fragment}
+
+Now, we need to consider which types of events we'll need to
+handle:
+
+\begin{Fragment}{Event Handlers}
+ «View Button Events»
+ «Urgency Events»
+ «Unresponsive Clients»
+ «Notice Events»
+ «Key Events»
+ «Client Menu Events»
+ «Tag Menu Events»
+\end{Fragment}
+
+\section{Bar Items}
+
+The bar is described by the files in the two directories |/lbar/| and
+|/rbar/| for buttons on the left and right side of the bar,
+respectively. The files act as control files (section
+\ref{sec:controlfiles}) with the contents:
+
+\begin{code}
+ color ‹Color Tuple›
+ label ‹Label›
+\end{code}
+
+A ‹Color Tuple› is defined as:
+
+\begin{code}
+ ‹Color Tuple› ≔ ‹foreground color› ‹background color› ‹border color›
+ ‹* Color› ≔ ‹RGB color› | ‹RGBA color›
+ ‹RGB color› ≔ #‹6 character RGB hex color code›
+ ‹RGBA color› ≔ rgba:‹red›/‹green›/‹blue›/‹alpha›
+\end{code}
+
+\noindent
+where all of the colors are represented as lowercase,
+hexidecimal values. In the case of RGBA colors, they may be 1--4
+characters long, though they will be standardized internally to
+2 characters.
+
+\medskip
+
+Let's define our basic theme information now:
+
+\begin{Fragment}{Theme Definitions}
+ normcolors=‘#000000 #c1c48b #81654f’
+ focuscolors=‘#000000 #81654f #000000’
+ background=‘#333333’
+ font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*’
+\end{Fragment}
+
+\subsection{View Buttons}
+
+With a basic understanding of bar items in mind, we can write
+our view event handlers:
+
+\index{events!CreateTag}
+\index{events!DestroyTag}
+\index{events!FocusTag}
+\index{events!UnfocusTag}
+\begin{Fragment}{View Button Events}
+ CreateTag) # CreateTag ‹Tag Name›
+ echo $normcolors $1 | wmiir create /lbar/$1;;
+ DestroyTag) # DestroyTag ‹Tag Name›
+ wmiir rm /lbar/$1;;
+ FocusTag) # FocusTag ‹Tag Name›
+ wmiir xwrite /lbar/$1 $focuscolors $1;;
+ UnfocusTag) # UnfocusTag ‹Tag Name›
+ wmiir xwrite /lbar/$1 $normcolors $1;;
+\end{Fragment}
+
+\subsection{Urgency}
+
+\index{events!UrgentTag|(}
+\index{events!NotUrgentTag|(}
+Windows can specify that they require attention, and in X11
+parlance, this is called urgency\footnote{\ICCCM{4.1.2.4}}. When
+a window requests attention as such, or declares that it's been
+satisfied, \wmii\ broadcasts an event for the client and an
+event for each view that it belongs to. It also fills in the
+layout box of any client deemed urgent. It's the job of a script
+to decide how to handle urgency events above and beyond that
+basic measure. The standard scripts simply mark urgent views
+with an asterisk:
+
+\begin{Fragment}{Urgency Events}
+ # The urgency events are ‘Client’ events when the program
+ # owning the window sets its urgency state. They're ‘Manager’
+ # events when wmii or the wmii user sets the state.
+ UrgentTag) # UrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
+ wmiir xwrite /lbar/$2 $2;;
+ NotUrgentTag) # NotUrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
+ wmiir xwrite /lbar/$2 $2;;
+\end{Fragment}
+\index{events!UrgentTag|)}
+\index{events!NotUrgentTag|)}
+
+\subsection{Notices}
+
+The standard scripts provide a custom Notice event for
+displaying status information. The events appear in the long bar
+between the left and right sides for five seconds.
+
+\begin{Fragment}{Notice Events}
+ Notice)
+ wmiir xwrite /rbar/!notice $line
+ kill $xpid 2>/dev/null # Let's hope this isn't reused...
+ { sleep 5; wmiir xwrite /rbar/!notice ‘ ’; } &
+ xpid = $!;;
+\end{Fragment}
+
+\section{Keys}
+
+\label{sec:keybindings}
+\index{key bindings}
+\index{filesystem!/!keys}
+\index{filesystem!/!event}
+Now to the part you've no doubt been waiting for: binding keys.
+When binding keys, you need to be aware of two files, |/keys|
+and |/event|. The former defines which keys \wmii\ needs to
+grab, and the latter broadcasts the events when they're pressed.
+
+Key names are specified as a series of modifiers followed by a
+key name, all separated by hyphens. Valid modifier names are
+|Control|, |Shift|, |Mod1| (usually Alt), |Mod2|, |Mod3|, |Mod4|
+(usually the Windows® key), and |Mod5|. Modifier keys can be
+changed via |xmodmap(1)|, the details of which are beyond the
+scope of this document.
+
+Key names can be detected by running |xev| from a
+terminal, pressing the desired key, and looking at the output
+(it's in the parentheses, after the keysym). Or, more simply,
+you can run the \man 1 {wikeyname} utility bundled with \wmii\
+and press the key you wish to bind.
+
+Examples of key bindings:
+
+\begin{description}
+ \item[Windows® key + Capital A] |Mod4-Shift-A|
+ \item[Control + Alt + Space] |Mod1-Control-Space|
+\end{description}
+
+Now, let's bind the keys we plan on using:
+
+\begin{Fragment}{Bind Keys}
+ {
+ cat <<!
+ Mod4-space
+ Mod4-d
+ Mod4-s
+ Mod4-m
+ Mod4-a
+ Mod4-p
+ Mod4-t
+ Mod4-Return
+ Mod4-Shift-space
+ Mod4-f
+ Mod4-Shift-c
+ Mod4-Shift-t
+ Mod4-h
+ Mod4-j
+ Mod4-k
+ Mod4-l
+ Mod4-Shift-h
+ Mod4-Shift-j
+ Mod4-Shift-k
+ Mod4-Shift-l
+ !
+ for i in 1 2 3 4 5 6 7 8 9 0; do
+ echo Mod4-$i
+ echo Mod4-Shift-$i
+ done
+ } | wmiir write /keys
+\end{Fragment}
+
+and lay a framework for processing their events:
+
+\begin{Fragment}{Key Events}
+ Key) # Key ‹Key Name›
+ case $1 in
+ «Motion Keys»
+ «Client Movement Keys»
+ «Column Mode Keys»
+ «Client Command Keys»
+ «Command Execution Keys»
+ «Tag Selection Keys»
+ «Tagging Keys»
+ esac;;
+\end{Fragment}
+
+\section{Click Menus}
+
+Sometimes, you have your hand on the mouse and don't want to
+reach for the keyboard. To help cope, \wmii\ provides a
+mouse-driven, single-click menu. The default configuration uses
+it for client and tag menus.
+
+\begin{Fragment}{Click Menu Initialization}
+ clickmenu() {
+ if res=$(wmii9menu -- “$@”); then eval “$res”; fi
+ }
+\end{Fragment}
+
+\section{Control Files}
+
+\label{sec:controlfiles}
+
+Several directories including the root, have control files,
+named |ctl|. These files are used to control the object (e.g., a
+client or tag) represented by the directory. Each line of the
+file, with the possible section of the first, represents a
+control variable and its value. In the case of all but the root
+|/ctl| file, the first line represents the id of the directory.
+In the case of |/tag/foo/ctl|, for instance, the first line
+should read |foo|. This is useful when dealing with the special
+|sel/| directories. For instance, when |foo| is the selected
+tag, the special |/tag/sel| directory is a link to |/tag/foo|,
+and the first line of |/tag/sel/ctl| will read |foo|, just as
+if you'd accessed |/tag/foo/ctl| directly.
+
+The rest of the lines, the control variables, can be modified by
+writing new values to the control file. For instance, if a
+client is fullscreen, its control file will contain the line:
+
+\begin{code}
+ fullscreen on
+\end{code}
+
+\noindent To restore the client from fullscreen, either of the
+following lines may be written to its control file:
+
+\begin{code}
+ fullscreen off
+ fullscreen toggle
+\end{code}
+
+When next read, the |fullscreen on| line will have been replaced
+with |fullscreen off|. No care need be taken to preserve the
+other contents of the file. They're generated anew each time
+it's read.
+
+\section{Clients}
+
+\def\clientlabel{/client/$\langle\mathit{client}\rangle$/}
+\index{filesystem!/client/*/@\clientlabel|(}
+Clients are represented by directories under the |/client/|
+tree. Subdirectory names represent the client's X11 window ID.
+The special |sel/| directory represents the currently selected
+client. The files in these directories are:
+
+\begin{description}
+ \item[ctl] The client's control file, containing the following
+ properties:
+ \index{filesystem!/client/*/@\clientlabel!ctl}
+ \begin{description}
+ \item[allow] The set of unusual actions the client is
+ allowed to perform, in the same format as the tag set.
+ \begin{description}
+ \item[activate] The client is allowed to activate
+ itself—that is, focus its window and, as the case may
+ require, uncollapse it and select a tag it resides on.
+ This flag must be set on a client if you wish it able to
+ activate itself from the system tray.
+ \end{description}
+ \item[floating] Defines whether this client is likely to
+ float when attached to a new view. May be |on|, |off|,
+ |always|, or |never|. Ordinarilly, the value changes
+ automatically whenever the window is moved between the
+ floating and managed layers. However, setting a value of
+ |always| or |never| overrides this behavior.
+ \item[fullscreen] The client's fullscreen state. When
+ |on|, the client is displayed fullscreen on all of its
+ views. Possible values are |on|, |off|, and |toggle|.
+ \item[group] The client's group ID, or |0| if not part of
+ a group. Clients tend to open with the same tags and in
+ the same columns as the last active member of their
+ group. Setting this property is only useful when done
+ via the rules file.
+ \item[kill] When written, the window is closed politely,
+ if possible.
+ \item[pid] Read-only value of the PID of the program that
+ owns the window, if the value is available and the
+ process is on the same machine as wmii.
+ \item[slay] When written, the client is disconnected
+ peremptorily. If the client's PID is available and the
+ process is the same machine as wmii, its parent process
+ is killed
+ \item[tags] The client's tags. The same as the tags file.
+ \item[urgent] The client's urgency state. When |on|, the
+ client's layout box will be highlighted. Possible values
+ are |on|, |off|, and |toggle|.
+ \end{description}
+ \item[props] The client's window class (the X11
+ |WM_CLASS|\footnote{\ICCCM{4.1.2.5}}
+ property) and title string, separated by colons. This file
+ is not writable.
+ \index{filesystem!/client/*/@\clientlabel!props}
+ \item[label] The client's window title. May be written to
+ change the client's title.
+ \index{filesystem!/client/*/@\clientlabel!label}
+ \item[tags]
+ \index{filesystem!/client/*/@\clientlabel!tags}
+ The client's tags. Tag names are separated by |+|, |-|, or
+ |^| signs. Tag names which directly follow a |+| sign are
+ added, while whose following a |-| sign are removed and
+ those following a |^| are toggled. If the value written
+ begins with one of these characters, the value is appended
+ to the clients tags rather than replacing them.
+
+ Tags formatted as |/‹regex›/| are treated as regular
+ expressions, which place the client on any extant matching
+ tag\footnote{While a client with a regex tag will always
+ appear in all matching views, it will not keep those views
+ in existence. When the last client explicitly tagged with a
+ view is removed, the view is deleted as soon as it becomes
+ inactive.}. Regular expression tags which directly follow a
+ minus sign are treated as exclusion expressions. For
+ example, the tag string |+/foo/-/food/| will match the tag
+ |foobar|, but not the tag |foodstand|.
+\end{description}
+
+\index{filesystem!/client/*/@\clientlabel|)}
+
+\subsection{Key Bindings}
+
+To control clients, we'll add the following key bindings:
+
+\begin{Fragment}{Client Command Keys}
+ Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
+ Mod4-f) wmiir xwrite /client/sel/ctl Fullscreen toggle;;
+\end{Fragment}
+
+And to manage their tags, we'll need:
+
+\begin{Fragment}{Tagging Keys}
+ Mod4-Shift-t)
+ # Get the selected client's id
+ c=$(wmiir read /client/sel/ctl | sed 1q)
+ # Prompt the user for new tags
+ tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
+ # Write them to the client
+ wmiir xwrite /client/$c/tags $tag;;
+ Mod4-Shift-[0-9])
+ wmiir xwrite /client/sel/tags ${1##*-};;
+\end{Fragment}
+
+\subsection{Click Menus}
+
+\index{events!ClientMouseDown}
+\begin{Fragment}{Client Menu Events}
+ ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
+ [ $2 = 3 ] && clickmenu \
+ “Delete:wmiir xwrite /client/$1/ctl kill” \
+ “Kill: wmiirxwrite /client/$1/ctl slay” \
+ “Fullscreen:wmiir xwrite /client/$1/ctl fullscreen on”
+\end{Fragment}
+
+\subsection{Unresponsive Clients}
+
+\index{events!UnresponsiveClient|(}
+When \wmii\ tries to close a window, it waits 8 seconds for the
+client to respond, and then lets its scripts decide what to do
+with it. The stock scripts prompt the user for input:
+
+\begin{Fragment}{Unresponsive Clients}
+ UnresponsiveClient) # UnresponsiveClient ‹Client ID›
+ {
+ # Use wihack to make the xmessage a transient window of
+ # the problem client. This will force it to open in the
+ # floaing layer of whatever views the client is attached to
+ resp=$(wihack -transient $1 \
+ xmessage -nearmouse -buttons Kill,Wait -print \
+ “The following client is not responding.” \
+ “What would you like to do?$(echo)” \
+ $(wmiir read /client/$1/label))
+ [ $resp = Kill ] && wmiir xwrite /client/$1/ctl slay
+ } &;;
+\end{Fragment}
+\index{events!UnresponsiveClient|)}
+
+\section{Views}
+
+\def\taglabel{/tag/$\langle\mathit{tag}\rangle$/}
+\index{filesystem!/tag/*/@\taglabel|(}
+Views are represented by directories under the |/tag/| tree. The
+special |sel/| directory represents the currently selected
+client. The |sel| tag is treated similarly elsewhere. The files
+in these directories are:
+
+\begin{description}
+ \item[ctl]
+ The view's control file. The properties are:
+ \index{filesystem!/tag/*/@\taglabel!ctl|(}
+ \begin{description}
+ \item[select ‹Area›] Select the column ‹Area›, where
+ ‹Area› is a 1-based column index, or |~| for the floating
+ area. It may be optionally preceded by ‹Screen›|:|, where
+ ‹Screen› is a 0-based Xinerama screen index, or “sel”. When
+ omitted, ‹Screen› defaults to 0, the primary screen.
+ \item[select ‹Area› ‹Client Index›] Select the column ‹Area›, and
+ the ‹Client Index›th client.
+ \item[select client ‹Client ID›] Select the client with the
+ X11 window ID ‹Client ID›.
+ \item[select ‹Direction›]
+ Select the client in ‹Direction› where ‹Direction› may be
+ one of ‹up $\wedge$ down $\wedge$ left $\wedge$ right›.
+ \item[send client ‹Client ID› ‹Area›] Send ‹Client ID› to
+ ‹Area›. ‹Area› may be |sel| for the selected area, and
+ |client ‹Client ID›| may be |sel| for the currently selected
+ client.
+ \item[send client ‹Client ID› ‹Direction›]
+ Send ‹Client ID› to a column or position in its column in
+ the given direction.
+ \item[send client ‹Client ID› toggle] If ‹Client ID› is
+ floating, send it to the managed layer. If it's managed,
+ send it to the floating layer.
+ \item[swap client ‹Client ID› \ldots] The same as the |send|
+ commands, but swap ‹Client ID› with the client at the given
+ location.
+ \item[colmode ‹Area› ‹Mode›] Set ‹Area›'s mode to ‹Mode›,
+ where ‹Mode› is a string of values similar to tag
+ specifications. Values which may be added and removed are as
+ follows for managed areas:
+
+ \begin{description}
+ \item[stack] One and only one client in the area is
+ uncollapsed at any given time. When a new client is
+ selected, it is uncollapsed and the previously selected
+ client is collapsed.
+ \item[max] Collapsed clients are hidden from view
+ entirely. Uncollapsed clients display an indicator
+ {\it‹n›/‹m›}, where ‹m› is the number of collapsed
+ clients directly above and below the client, plus one,
+ and ‹n› is the client's index in the stack.
+ \item[default] Like subtracting the stack mode, but all
+ clients in the column are given equal height.
+ \end{description}
+
+ For the floating area, the values are the same, except that
+ in |max| mode, floating clients are hidden when the managed
+ layer is selected.
+ \item[grow ‹Frame› ‹Direction› {[‹Amount›]}] Grow ‹Frame› in
+ the given direction, by ‹Amount›. ‹Amount› may be any
+ integer, positive or negative. If suffixed with |px|,
+ it specifies an exact pixel amount, otherwise it specifies a
+ “reasonable increment”. Defaults to 1.
+
+ ‹Frame› may be one of:
+ \begin{itemize}
+ \item client ‹Client ID›
+ \item ‹Area› ‹Client Index›
+ \end{itemize}
+ \item[nudge ‹Frame› ‹Direction› {[‹Amount›]}] Like
+ |grow|, but move the client in ‹Direction› instead of
+ resizing it.
+ \end{description}
+ \index{filesystem!/tag/*/@\taglabel!ctl|)}
+\end{description}
+
+\index{filesystem!/tag/*/@\taglabel|)}
+
+\subsection{Key Bindings}
+
+We'll use the following key bindings to interact with views:
+
+\begin{Fragment}{Motion Keys}
+ Mod4-h) wmiir xwrite /tag/sel/ctl select left;;
+ Mod4-l) wmiir xwrite /tag/sel/ctl select right;;
+ Mod4-k) wmiir xwrite /tag/sel/ctl select up;;
+ Mod4-j) wmiir xwrite /tag/sel/ctl select down;;
+ Mod4-space) wmiir xwrite /tag/sel/ctl select toggle;;
+\end{Fragment}
+
+\begin{Fragment}{Client Movement Keys}
+ Mod4-Shift-h) wmiir xwrite /tag/sel/ctl send sel left;;
+ Mod4-Shift-l) wmiir xwrite /tag/sel/ctl send sel right;;
+ Mod4-Shift-k) wmiir xwrite /tag/sel/ctl send sel up;;
+ Mod4-Shift-j) wmiir xwrite /tag/sel/ctl send sel down;;
+ Mod4-Shift-space) wmiir xwrite /tag/sel/ctl send sel toggle;;
+\end{Fragment}
+
+\begin{Fragment}{Column Mode Keys}
+ Mod4-d) wmiir xwrite /tag/sel/ctl colmode sel -stack-max;;
+ Mod4-s) wmiir xwrite /tag/sel/ctl colmode sel stack-max;;
+ Mod4-m) wmiir xwrite /tag/sel/ctl colmode sel stack+max;;
+\end{Fragment}
+
+\subsection{Click Menus}
+
+\index{events!LeftBarMouseDown}
+\begin{Fragment}{Tag Menu Events}
+ LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
+ [ $1 = 3 ] && clickmenu \
+ “Delete:delete_view $2”
+\end{Fragment}
+
+\section{Command and Program Execution}
+
+Perhaps the most important function we need to provide for is
+the execution of programs. Since \wmii\ users tend to use
+terminals often, we'll add a direct shortcut to launch one.
+Aside from that, we'll add a menu to launch arbitrary programs
+(with completions) and a separate menu to launch wmii specific
+commands.
+
+We use |wmiir setsid| to launch programs with their own session
+IDs to prevent untoward effects when this script dies.
+
+\begin{Fragment}{Command Execution Initialization}
+ terminal() { wmiir setsid xterm “$@” }
+ proglist() {
+ IFS=:
+ wmiir proglist $1 | sort | uniq
+ unset IFS
+ }
+\end{Fragment}
+
+\subsection{Key Bindings}
+\begin{Fragment}{Command Execution Keys}
+ Mod4-Return) terminal & ;;
+ Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
+ Mod4-a) {
+ set -- $(proglist $WMII_CONFPATH | wimenu)
+ which=$(which which)
+ prog=$(PATH=$WMII_CONFPATH $which $1); shift
+ eval exec $prog “$@”
+ } &;;
+\end{Fragment}
+
+\section{The Root}
+
+The root filesystem contains the following:
+
+\index{!filesystem!/|(}
+\begin{description}
+ \item[ctl] The control file. The properties are:
+ \index{filesystem!/!ctl}
+ \begin{description}
+ \item[bar on ‹top $\wedge$ bottom›] Controls where the bar
+ is shown.
+ \item[bar off] Disables the bar entirely.
+ \item[border] The border width, in pixels, of floating
+ clients.
+ \item[colmode ‹Mode›] The default column mode for newly
+ created columns.
+ \item[focuscolors ‹Color Tuple›] The colors of focused
+ clients.
+ \item[normcolors ‹Color Tuple›] The colors of unfocused
+ clients and the default color of bar buttons.
+ \item[font ‹Font›] The font used throughout \wmii. If
+ prefixed with |xft:|, the Xft font renderer is used, and
+ fonts may be antialiased. Xft font names follow the
+ fontconfig formula. For instance, 10pt, italic Lucida
+ Sans would be specified as
+
+ \begin{code}
+ xft:Lucida Sans-10:italic
+ \end{code}
+
+ See \man 1 {fc-match}.
+
+ \item[grabmod ‹Modifier Keys›] The key which must be
+ pressed to move and resize windows with the mouse
+ without clicking hot spots.
+ \item[incmode ‹Mode›] Controls how X11 increment hints are
+ handled in managed mode. Possible values are:
+ \begin{description}
+ \item[ignore] Increment hints are ignored entirely.
+ Clients are stretched to fill their full allocated
+ space.
+ \item[show] Gaps are shown around managed client
+ windows when their increment hints prevent them from
+ filling their entire allocated space.
+ \item[squeeze] When increment hints cause gaps to show
+ around clients, \wmii\ will try to adjust the sizes
+ of the clients in the column to minimize lost space.
+ \end{description}
+ \item[view ‹Tag›] Change the currently visible view.
+ \item[exec ‹Command›] Replaces this \wmii\ instance with
+ ‹Command›. ‹Command› is split according to rc quoting
+ rules, and no expansion occurs. If the command fails to
+ execute, \wmii\ will respawn.
+ \item[spawn ‹Command›] Spawns ‹Command› as it would spawn
+ |wmiirc| at startup. If ‹Command› is a single argument
+ and doesn't begin with |/| or |./|,%
+ \hskip 1ex|$WMII_CONF|\-|PATH| is
+ searched for the executable. Otherwise, the whole
+ argument is passed to the shell for evaluation.
+ \end{description}
+ \item[keys] The global keybindings. See section \ref{sec:keybindings}.
+ \index{filesystem!/!keys|primary}
+ \item[event] The global event feed. See section \ref{sec:keybindings}.
+ \index{filesystem!/!event|primary}
+ \item[colrules]
+ \index{filesystem!/!colrules}
+ The |/colrules| file contains a list of
+ rules which affect the width of newly created columns.
+ Rules have the form:
+
+ \begin{quote}\texttt{
+ /‹regex›/ -> ‹width›{\color{gray}[}+‹width›{\color{gray}]*}}
+ \end{quote}
+
+ Where,
+
+ \begin{code}
+ ‹width› ≔ ‹percent of screen› | ‹pixels›px
+ \end{code}
+
+ When a new column, ‹n›, is created on a view whose name
+ matches ‹regex›, it is given the ‹n›th supplied ‹width›.
+ If there is no ‹n›th width, it is given
+ $1/\mbox{‹ncol›th}$ of the screen.
+
+ \item[rules]
+ \index{filesystem!/!rules}
+ The |/rules| file contains a list of
+ rules similar to the colrules. These rules set
+ properties for a client when it is created.
+ Rules are specified:
+
+ \begin{quote}\texttt{
+ /‹regex›/ -> ‹key›{\color{gray}=}‹value› {\color{gray}\ldots}}
+ \end{quote}
+
+ When a client's ‹name›:‹class›:‹title› matches
+ ‹regex›, the matching rules are applied. For each
+ ‹key›=‹value› pair, the |ctl| file property matching
+ ‹key› is set to ‹value›. Additionally, the following
+ keys are accepted and have special meaning:
+
+ \begin{description}
+ \item[continue]
+ Normally, when a matching rule is encountered,
+ rule matching stops. When the continue key is
+ provided (with any value), matching continues at
+ the next rule.
+ \item[force-tags]
+ Like tags, but overrides any settings obtained
+ obtained from the client's group or from the
+ |_WMII_TAGS| window property.
+ \end{description}
+
+\end{description}
+
+\index{!filesystem!/|)}
+
+\subsection{Configuration}
+
+We'll need to let \wmii\ know about our previously defined theme
+information:
+
+\begin{Fragment}{Configuration}
+ «Theme Definitions»
+
+ xsetroot -solid $background
+ wmiir write /ctl <<!
+ border 2
+ focuscolors $focuscolors
+ normcolors $normcolors
+ font $font
+ grabmod Mod4
+ !
+\end{Fragment}
+
+\subsection{Key Bindings}
+
+And we need a few more key bindings to select our views:
+
+\begin{Fragment}{Tag Selection Keys}
+ Mod4-t)
+ # Prompt the user for a tag
+ tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
+ # Write it to the filesystem.
+ wmiir xwrite /ctl view $tags;;
+ Mod4-[0-9])
+ wmiir xwrite /ctl view ${1##*-};;
+\end{Fragment}
+
+\section{Tieing it All Together}
+
+\begin{code}
+ #!/bin/sh
+ «Click Menu Initialization»
+ «Command Execution Initialization»
+
+ «Configuration»
+
+ «Bind Keys»
+ «Event Loop»
+\end{code}
+
+\section{The End Result}
+
+For clarity, here is the end result:
+
+\begin{code}
+ #!/bin/sh
+ # «Click Menu Initialization»
+ clickmenu() {
+ if res=$(wmii9menu -- “$@”); then eval “$res”; fi
+ }
+ # «Command Execution Initialization»
+ terminal() { wmiir setsid xterm “$@” }
+ proglist() {
+ IFS=:
+ wmiir proglist $1 | sort | uniq
+ unset IFS
+ }
+
+ # «Configuration»
+ # «Theme Definitions»
+ normcolors=‘#000000 #c1c48b #81654f’
+ focuscolors=‘#000000 #81654f #000000’
+ background=‘#333333’
+ font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*’
+
+ xsetroot -solid $background
+ wmiir write /ctl <<!
+ border 2
+ focuscolors $focuscolors
+ normcolors $normcolors
+ font $font
+ grabmod Mod4
+ !
+
+ # «Bind Keys»
+ {
+ cat <<!
+ Mod4-space
+ Mod4-d
+ Mod4-s
+ Mod4-m
+ Mod4-a
+ Mod4-p
+ Mod4-t
+ Mod4-Return
+ Mod4-Shift-space
+ Mod4-f
+ Mod4-Shift-c
+ Mod4-Shift-t
+ Mod4-h
+ Mod4-j
+ Mod4-k
+ Mod4-l
+ Mod4-Shift-h
+ Mod4-Shift-j
+ Mod4-Shift-k
+ Mod4-Shift-l
+ !
+ for i in 1 2 3 4 5 6 7 8 9 0; do
+ echo Mod4-$i
+ echo Mod4-Shift-$i
+ done
+ } | wmiir write /keys
+
+ # «Event Loop»
+ # Broadcast a custom event
+ wmiir xwrite /event Start wmiirc
+
+ # Turn off globbing
+ set -f
+ # Open /event for reading
+ wmiir read /event |
+ # Read the events line by line
+ while read line; do
+ # Split the line into words, store in $@
+ set -- $line
+ event=$1; shift
+ line = "$(echo $line | sed ‘s/^[^ ]* //’ | tr -d ‘\n’)"
+
+ # Process the event
+ case $event in
+ Start) # Quit when a new instance starts
+ [ $1 = wmiirc ] && exit;;
+
+ # «Event Handlers»
+ # «View Button Events»
+ CreateTag) # CreateTag ‹Tag Name›
+ echo $normcolors $1 | wmiir create /lbar/$1;;
+ DestroyTag) # DestroyTag ‹Tag Name›
+ wmiir rm /lbar/$1;;
+ FocusTag) # FocusTag ‹Tag Name›
+ wmiir xwrite /lbar/$1 $focuscolors $1;;
+ UnfocusTag) # UnfocusTag ‹Tag Name›
+ wmiir xwrite /lbar/$1 $normcolors $1;;
+
+ # «Urgency Events»
+ # The urgency events are ‘Client’ events when the program
+ # owning the window sets its urgency state. They're ‘Manager’
+ # events when wmii or the wmii user sets the state.
+ UrgentTag) # UrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
+ wmiir xwrite /lbar/$2 $2;;
+ NotUrgentTag) # NotUrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
+ wmiir xwrite /lbar/$2 $2;;
+
+ # «Unresponsive Clients»
+ UnresponsiveClient) # UnresponsiveClient ‹Client ID›
+ {
+ # Use wihack to make the xmessage a transient window of
+ # the problem client. This will force it to open in the
+ # floaing layer of whatever views the client is attached to
+ resp=$(wihack -transient $1 \
+ xmessage -nearmouse -buttons Kill,Wait -print \
+ “The following client is not responding.” \
+ “What would you like to do?$(echo)” \
+ $(wmiir read /client/$1/label))
+ [ $resp = Kill ] && wmiir xwrite /client/$1/ctl slay
+ } &;;
+
+ # «Notice Events»
+ Notice)
+ wmiir xwrite /rbar/!notice $line
+ kill $xpid 2>/dev/null # Let's hope this isn't reused...
+ { sleep 5; wmiir xwrite /rbar/!notice ‘ ’; } &
+ xpid = $!;;
+
+ # «Key Events»
+ Key) # Key ‹Key Name›
+ case $1 in
+ # «Motion Keys»
+ Mod4-h) wmiir xwrite /tag/sel/ctl select left;;
+ Mod4-l) wmiir xwrite /tag/sel/ctl select right;;
+ Mod4-k) wmiir xwrite /tag/sel/ctl select up;;
+ Mod4-j) wmiir xwrite /tag/sel/ctl select down;;
+ Mod4-space) wmiir xwrite /tag/sel/ctl select toggle;;
+
+ # «Client Movement Keys»
+ Mod4-Shift-h) wmiir xwrite /tag/sel/ctl send sel left;;
+ Mod4-Shift-l) wmiir xwrite /tag/sel/ctl send sel right;;
+ Mod4-Shift-k) wmiir xwrite /tag/sel/ctl send sel up;;
+ Mod4-Shift-j) wmiir xwrite /tag/sel/ctl send sel down;;
+ Mod4-Shift-space) wmiir xwrite /tag/sel/ctl send sel toggle;;
+
+ # «Column Mode Keys»
+ Mod4-d) wmiir xwrite /tag/sel/ctl colmode sel -stack-max;;
+ Mod4-s) wmiir xwrite /tag/sel/ctl colmode sel stack-max;;
+ Mod4-m) wmiir xwrite /tag/sel/ctl colmode sel stack+max;;
+
+ # «Client Command Keys»
+ Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
+ Mod4-f) wmiir xwrite /client/sel/ctl fullscreen toggle;;
+
+ # «Command Execution Keys»
+ Mod4-Return) terminal & ;;
+ Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
+ Mod4-a) {
+ set -- $(proglist $WMII_CONFPATH | wimenu)
+ prog=$(PATH=$WMII_CONFPATH which $1); shift
+ eval exec $prog “$@”
+ } &;;
+
+ # «Tag Selection Keys»
+ Mod4-t)
+ # Prompt the user for a tag
+ tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
+ # Write it to the filesystem.
+ wmiir xwrite /ctl view $tag;;
+ Mod4-[0-9])
+ wmiir xwrite /ctl view ${1##*-};;
+
+ # «Tagging Keys»
+ Mod4-Shift-t)
+ # Get the selected client's id
+ c=$(wmiir read /client/sel/ctl | sed 1q)
+ # Prompt the user for new tags
+ tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
+ # Write them to the client
+ wmiir xwrite /client/$c/tags $tag;;
+ Mod4-Shift-[0-9])
+ wmiir xwrite /client/sel/tags ${1##*-};;
+
+ esac;;
+
+ # «Client Menu Events»
+ ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
+ [ $2 = 3 ] && clickmenu \
+ “Delete:wmiir xwrite /client/$1/ctl kill” \
+ “Kill:wmiir xwrite /client/$1/ctl slay” \
+ “Fullscreen:wmiir xwrite /client/$1/ctl fullscreen on”
+
+ # «Tag Menu Events»
+ LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
+ [ $1 = 3 ] && clickmenu \
+ “Delete:delete_view $2”
+ esac
+ done
+\end{code}
+
diff --git a/doc/gettingstarted.tex b/doc/gettingstarted.tex
@@ -0,0 +1,294 @@
+\chapter{Getting Started}
+
+This section will walk you through your first \wmii\ startup.
+For your first experience, we recommend running \wmii\ in its
+own X session, so you can easily switch back to a more
+comfortable environment if you get lost. Though you may start
+\wmii\ from a session manager in your day to day use, these
+instructions will use |xinit|. To begin with, copy this file
+to your home directory, so we can open it in your new X session.
+Then setup your |~/.xinitrc| as follows:
+
+\begin{code}
+ cd
+
+ # Start a PDF viewer with this guide. Use any viewer
+ # you're comfortable with.
+ xpdf wmii.pdf &
+
+ # Launch wmii
+ exec wmii
+
+ # That was easy.
+\end{code}
+
+Before you run |xinit|, make sure you know how to switch
+between terminals. Depending on your system, your current X
+session is probably on terminal 5 or 7. You should be able to
+switch between your terminals by pressing
+Ctrl-Alt-F$\langle n\rangle$. Assuming that your current X
+session is on terminal 7, you should be able to switch between
+it and your new session by pressing Ctrl-Alt-F7 and Ctrl-Alt-F8.
+Now you should be ready to start \wmii. When you run the
+following command, you should be presented with a new X session
+running wmii and a PDF viewer showing this document.
+
+\begin{code}
+ xinit
+\end{code}
+
+When you're there, find this page in the new PDF viewer and
+continue.
+
+\section{Your First Steps}
+
+If everything went according to plan, you should be viewing this
+from a nearly empty \wmii\ session. We're going to be using the
+keyboard a lot, so let's start with a convention for key
+notation. We'll be using the key modifiers Control, Alt, Shift,
+and Meta\footnote{The Windows$^{\mbox{\tiny®}}$ key on most
+keyboards. The Penguin key on the more tongue in cheek
+varieties.}, which we'll specify as C-, A-, S-, and M-,
+respectively. So, <C-S-a> means pressing ‘|a|’ while holding
+|Control| and |Shift|. We'll also express mouse clicks this
+way, with <M-Mouse1> signifying a press of the right mouse
+button, with the Meta key depressed. Buttons 4 and 5 are the up
+and down scroll wheel directions, respectively.
+
+\subsection{Floating Mode}
+
+Beginning with what's familiar to most users, we'll first explore
+floating mode. First, we need to select the floating layer.
+Press <M-Space>. You should see the titlebar of this window
+change color. Now, press <M-Return> to launch a terminal.
+The easiest way to drag the terminal around is to press and hold
+<M-Mouse1> over the window and simply drag the window
+around. You should be able to drag the window anywhere onscreen
+without ever releasing the mouse button. As you drag near the
+screen edges, you should notice a snap. If you try to drag the
+window fully off-screen, you'll find it constrained so that a
+portion always remains visible. Now, release the window and move
+the mouse toward one of its corners. Press and hold
+<M-Mouse3>\footnote{The right button.}. As you drag the
+mouse around, you should see the window resized accordingly.
+
+To move the window without the modifier key, move the pointer
+over the layout box to the left of its titlebar. You should see
+the cursor change. Now, simply click and drag. To resize it,
+move the pointer toward the window's edge until you see the
+cursor change, and again, click and drag. Now, to close the
+window, move the mouse over the windows titlebar, press and hold
+<Mouse3>, select |Delete|, and release it. You should
+see this window's titlebar return to its original color,
+indicating that it's regained focus.
+
+\subsection{Managed Mode}
+
+Now, for the fun part. We'll start exploring managed mode by
+looking at the basics of columns. In the default configuration,
+columns have three modes:
+
+\begin{description}
+ \item[Stack] <M-s> The default mode for new columns. Only one window
+ is fully visible per column at once. The others only display
+ their title bars. When new windows are added to the column,
+ the active window collapses, and the new one takes its
+ place. Whenever a collapsed client is selected, the active
+ window is collapsed to take its place.
+ \item[Max] <M-m> Like stack mode, but the titlebars of collapsed
+ clients are hidden.
+ \item[Default] <M-d> Multiple uncollapsed windows may be visible at
+ once. New windows split the space with the other uncollapsed
+ windows in their vicinity. Windows may still be collapsed by
+ shrinking them to the size of their titlebars. At this
+ point, the behavior of a stack of collapsed and uncollapsed
+ clients is similar to that of stack mode.
+\end{description}
+
+Before we open any new windows in managed mode, we need to
+explore the column modes a bit. Column modes are activated with
+the key bindings listed above. This column should be in stack
+mode now. Watch the right side of the titlebar as you press
+<M-m> to enter max mode. You should see an indicator appear.
+This tells you the number of hidden windows directly above and
+below the current window, and its position in that stack. Press
+<M-d> to enter default mode. Now we're ready to open another
+client. Press <M-Return> to launch another terminal. Now,
+press <M-S-l> to move the terminal to a new column to the
+right of this one. Once it's there, press <M-Return> two
+more times to launch two more terminals. Now that you have more
+than one window in a column, cycle through the three column
+modes again until they seem familiar.
+
+\subsection{Keyboard Navigation}
+
+To begin, switch back to default mode. The basic keyboard
+navigation keys, <M-h>, <M-j>, <M-k>, and <M-l>,
+derive from vi, and represent moving left, down, up, and right
+respectively. Try selecting each of the four windows currently
+visible on screen. Notice that navigation wraps from one side of
+the screen to the other, and from the top to the bottom. Now,
+return to the write column, switch to stack mode, and select
+each of the three terminals again. Do the same in max mode,
+paying careful attention to the indicator to the right of the
+titlebar.
+
+Now that you can select windows, you'll want to move them
+around. To move a window, just add the Shift key to the
+direction keys. So, to move a window left, instead of <M-h>,
+type <M-S-h>. Now, experiment with moving windows, just as
+you did with navigating them, in each of the three column modes.
+Once you're comfortable with that, move a window to the floating
+layer. Since we toggled between the floating and managed layers
+with <M-Space>, we'll move windows between them with
+<M-S-Space>. Try moving some windows back and forth until it
+becomes familiar. Now, move several windows to the floating
+layer and try switching between them with the keyboard. You'll
+notice that <M-h> and <M-l> don't function in the
+floating layer. This is for both historical and logistical
+reasons. <M-j> and <M-k> cycle through floating windows
+in order of their most recent use.
+
+\subsection{Mouse Navigation}
+
+\wmii\ uses the “sloppy focus” model, which is to say, it focuses
+windows when the mouse enters them and when you click them. It
+focuses windows only when you select them with the keyboard,
+click their titlebars, or press click them with <M-Mouse2>.
+Collapsed windows may be opened with the mouse by clicking their
+titlebars. Moving and resizing floating windows should be
+largely familiar, and has already been covered. The same can't
+be said for managed windows.
+
+Let's begin working with the mouse in the managed layer. Return
+to a layout with this document in a column on the left, and
+three terminals in a column to the right. Switch the right
+column to default mode. Now, bring the mouse to the top of the
+third terminal's titlebar until you see a resize cursor. Click
+and drag the titlebar to the very top of the screen. Now, move
+the cursor to the top of the second terminal's titlebar and drag
+it to the very bottom of the screen. Press <M-d> to restore the
+terminals to their original sizes. Now, click and hold the
+layout box of the second terminal. Drag it to the middle of the
+terminal's window and release. Click and hold the layout box of
+the third terminal and drag it to the middle of the first
+terminal's window. Finally, drag the first terminal's layout box
+to halfway down this window. <M-Mouse1> works to the same
+effect as dragging the layout box, but allows you to click
+anywhere in the window.
+
+Now that you've seen the basics of moving and dragging windows,
+let's move on to columns. Click and drag the border between the
+two columns. If that's a difficult target to click, there's a
+triangle at the top of the division between the two columns that
+you can click and drag as well. If that's still too hard a
+target, try using <M-Mouse3>, which works anywhere and provides
+much richer functionality.
+
+\subsection{Window Focus and Selection}
+
+For the purposes of keyboard navigation, \wmii\ keeps track of
+which window is currently selected, and confers its titlebar a
+different color scheme from the other windows. This window is
+the basis of relative motion commands, such as “select the
+window to the left”, and the target of commands such as “close
+this window”. Normally, the selected window is the same as the
+focused window, i.e., the window that receives keyboard events.
+Some applications, however, present strange corner cases.
+
+\begin{description}
+ \item[Focused, selected window] This is the normal case of a
+ window which is both selected and has the keyboard focus.
+ \titlebar{selected}
+ \item[Unfocused, unselected window] This is the normal case for an
+ unselected window which does not have the keyboard focus.
+ \titlebar{unselected}
+ \item[Unfocused, selected window] This is the first unusual
+ case. This is the selected window, for the purposes of
+ keyboard navigation, but it does not receive keyboard events.
+ A good example is an onscreen keyboard, which will receive
+ mouse clicks and translate them to keyboard events, but
+ won't absorb those keyboard events itself. Other examples
+ include any window whilst another (such as \wimenu) has
+ grabbed the keyboard.
+ \titlebar{unfocused}
+ \item[Focused, unselected window] This is the second unusual
+ focus case. The window has the keyboard focus, but for the
+ purposes of keyboard navigation, it is not considered
+ selected. In the case of an onscreen keyboard, this is the
+ window which will receive the generated events. In the case
+ of a keyboard grab, the will likely be the window holding
+ the grab.
+ \titlebar{focused}
+\end{description}
+
+\section{Running Programs}
+
+You've already seen the convenient key binding to launch a
+terminal, but what about other programs? To get a menu of all of
+the executables in your path, type <M-p>. This should replace
+the bar at the bottom of the screen with a prompt, followed by a
+string of completions. Start typing the name of a program that
+you want to open. You can press <Tab> and <S-Tab> to cycle
+through the completions, or you can just press <Return> to
+select the first one. If you want to execute a more complex
+command, just type it out and press <Return>. If you want to
+recall that command later, use \wimenu's history. Start typing
+the command you want and then press <C-p> until you come to it.
+
+When you're done with a program, you'll probably want an easy
+way to close it. The first way is to ask the program to close
+itself. Since that can be tedious (and sometimes impossible),
+\wmii\ provides other ways. As mentioned, you can right click
+the titlebar and select |Delete|. If you're at the keyboard,
+you can type <M-S-c>. These two actions cause \wmii\ to ask
+nicely that the program exit. In those sticky cases where the
+program doesn't respond, \wmii\ will wait 10 seconds before
+prompting you to kill the program. If you don't feel like
+waiting, you can select |Kill| from the window's titlebar
+menu, in which case \wmii\ will forcefully and immediately kill
+it. Beware, killing clients is a last resort. In cases where the
+same program opens multiple windows, killing one will kill them
+all—without warning.
+
+\section{Using Views}
+
+As already noticed, \wmii's concept of virtual workspaces is
+somewhat unique, so let's begin exploring it. Open up a terminal
+and press <M-S-2>. You should see a new button on the bar at the
+bottom of the screen. When you click it, you should see your
+original terminal. Press <M-1> to come back here. Now, press
+<M-3>, and <M-1> again to return here once more. Notice that the
+views were created when needed, and destroyed when no longer
+necessary. If you want to select a view with a proper name, use
+<M-t> and enter the name. Other than the dynamic creation of
+views, this is still similar to the familiar X11 workspace
+model. But that's just the beginning of \wmii's model. Open a new
+terminal, and type:
+
+\begin{code}
+ echo ‘Hello world!’
+\end{code}
+
+\noindent Now, type <M-S-t>. In the menu that appears, enter
+|1+2+3|. Now, visit the views |1|, |2|, and |3|, and you'll see
+the client on each. To remove a tag, type <M-S-t> again, and
+this time enter |-2|. You'll notice that the client is no longer
+on the |2| view. Finally, tag names needn't be discrete,
+ordinary strings. They can also be regular expressions. Select
+the terminal again, and enter |+/^5/|. Now, switch to the |5|
+view. Now try the |6| view. Finally, type <M-t> and enter |50|
+to check the |50| view. Clients tagged with regular expressions
+are attached to any matching views when they're created. So,
+when you switch to an empty view, or tag a client with a new
+tag, any clients with matching regular expressions are
+automatically added to it. When all explicitly tagged clients
+disappear from the view, and it's no longer visible, clients
+held there by regular expressions are automatically removed.
+
+\section{Learning More}
+
+For full tables of the standard key bindings, and descriptions
+of the precise semantics of the topics discussed above, you
+should refer to \wmii's |man| pages.
+
diff --git a/doc/introduction.tex b/doc/introduction.tex
@@ -0,0 +1,166 @@
+\chapter{Introduction}
+
+\wmii\ is a simple but powerful window manager for the X Window
+System. It provides both the classic (“floating”) and tiling
+(“managed”) window management paradigms, which is to say, it does
+the job of managing your windows, so you don't have to. It also
+provides programability by means of a simple file-like
+interface, which allows the user to program in virtually any
+language he chooses. These basic features have become
+indispensable to the many users of \wmii\ and other similar
+window managers, but they come at a cost. Though our penchant
+for simplicity makes \wmii's learning curve significantly
+shorter than most of its competitors, there's still a lot to
+learn. The rest of this guide will be devoted to familiarizing
+new users with \wmii's novel features and eccentricities, as
+well as provide advanced users with an in-depth look at our
+customization facilities.
+
+\section{Concepts}
+
+As noted, \wmii\ provides two management styles:
+
+\begin{description}
+ \item[Managed] This is the primary style of window management
+ in \wmii. Windows managed in this style are automatically
+ arranged by \wmii\ into columns. Columns are created and
+ destroyed on demand. Individual windows in the column may be
+ moved or resized, and are often collapsed or hidden
+ entirely. Ad-hoc stacks of collapsed and uncollapsed windows
+ allow the user to efficiently manage their tasks. When
+ switching from an active to a collapsed window, the active
+ window collapses and the collapsed one effectively takes
+ its place.
+
+ Managed windows have an unadorned titlebar:
+
+ \titlebar{managed}
+
+ \item[Floating] Since some programs aren't designed in ways
+ conducive to the managed work flow, \wmii\ also provides the
+ classic “floating” window management model. Windows managed
+ in this model float above the managed windows and may be moved
+ freely about. Other than automatic placement of new windows
+ and snapping of edges, \wmii\ doesn't manage floating
+ windows at all.
+
+ Floating windows are indicated by a decorated titlebar:
+
+ \titlebar{floating}
+
+ \item[Fullscreen] Fullscreen mode is actually a subset of the
+ floating style. Windows may be toggled to and from
+ fullscreen mode at will. When fullscreen, windows reside in
+ the floating layer, above the managed windows. They have no
+ borders or titlebars, and occupy the full area of the
+ screen. Other than that, however, they're not special in any
+ way. Other floating windows may appear above them and the
+ user can still select, open, and close other windows at
+ will.
+\end{description}
+
+\subsection{The Filesystem}
+
+All of \wmii's customization is done via a virtual filesystem.
+Since the filesystem is implemented in the standardized \ninep\
+protocol, it can be accessed in many ways. \wmii\ provides a
+simple command-line client, \wmiir, but many alternatives exist,
+including libraries for Python, Perl, Ruby, PHP, and C. It can
+even be mounted, either by Linux's 9p.ko kernel module or
+indirectly via FUSE.
+
+The filesystem that \wmii\ provides is “virtual”, which is to
+say that it doesn't reside on disk anywhere. In a sense, it's a
+figment of \wmii's imagination. Files, when read, represent
+\wmii's current configuration or state. When written, they
+perform actions, update the UI, etc. For instance, the directory
+|/client/| contains a directory for each window that \wmii\
+is currently managing. Each of those directories, in turn,
+contains files describing the client's properties (its title,
+its views\footnote{Views in \wmii\ are akin to workspaces or
+virtual desktops in other window managers, but with some subtle
+differences.}, its state). Most files can be written to update
+the state they describe. For instance,
+|/client/sel/ctl| describes the state of the selected
+client. If a client is fullscreen, it contains the line:
+
+\begin{code}
+ fullscreen on
+\end{code}
+
+\noindent To change this, you'd update the file with the line
+% XXX: Line broken at /ctl cmd.
+|fullscreen off| or even |fullscreen| |toggle| to toggle
+the client's fullscreen state.
+
+The concept of controlling a program via a filesystem derives
+from \plannine, where such interfaces are extensive and well
+proven\footnote{The concept has also taken hold on most Unixes
+in the form of \texttt{/proc} and \texttt{/sys} virtual
+filesystems, but tends to be very kernel-centric. On \plannine,
+where the model is more pervasive, there are more virtual
+filesystems for user-level applications than for the kernel.}.
+The metaphor has shown itself to be quite intuitive to Unix
+users, once the shock of a “virtual” filesystem wears off. The
+flexibility of being able to control \wmii\ from myriad
+programming languages, including the standard Unix shell and
+even from the command line, is well worth the shock.
+
+\subsection{Views and Tags}
+
+Like most X11 window managers, \wmii\ provides virtual
+workspaces. Unlike other window managers though, \wmii's
+workspaces are created and destroyed on demand. Instead of being
+sent to a workspace, windows in \wmii\ are tagged with any
+number of names. Views are created dynamically from these tags,
+and automatically if the user tries to access them. For
+instance, if a window is given the tags ‘foo’ and ‘bar’, the two
+views ‘foo’ and ‘bar’ are created, if they don't already exist.
+The window is now visible on both of them. Moreover, tags can be
+specified as regular expressions. So, a client tagged with {\tt
+\verb+/^foo/+} will appear on any view named ‘foo’, ‘foo:bar’,
+and so forth. Any time a client is tagged with a matching tag,
+or the user opens a matching view, the window is automatically
+added to it.
+
+\subsection{The Bar}
+
+\wmii\ provides a general purpose information bar at the top or
+bottom of the screen. The bar is divided into a left and a right
+section. Each section is made up of buttons, with a single
+button spanning the gap between the two sides. Buttons can be
+individually styled and can hold any text content the user
+wishes. By convention, the buttons to the left show view names,
+and those to the right display status information.
+
+\subsection{The Menus}
+
+\wmii\ includes two simple, external menu programs. The first,
+\wimenu, is keyboard-based, and is used to launch programs and
+generally prompt the user for input. It provides a list of
+completions which are automatically filtered as you type. The
+second, \wiIXmenu, is mouse-based, and is generally used to
+provide context menus for titlebars and view buttons. Both menus
+can be easily launched from shell scripts or the command line,
+as well as from more complex scripting languages.
+
+\subsection{The Keyboard}
+
+\wmii\ is a very keyboard friendly window manager. Most actions
+can be performed without touching the mouse, including
+launching, closing, moving, resizing, and selecting programs.
+New keybindings of any complexity can easily be added to handle
+any missing functionality, or to simplify any repetitive tasks.
+
+\subsection{The Mouse}
+
+Despite being highly keyboard-accessible, \wmii\ strives to be
+highly mouse accessible as well. Windows can be moved or resized
+by dragging their window borders. When combined with a key
+press, they can be moved, resized, or raised by dragging any
+visible portion of the window. Mouse menus are accessed with a
+single click and drag. View buttons in the bar and client
+titlebars respond to the mouse wheel; view buttons can be
+activated by dragging any draggable object (e.g., a file from a
+file manager) over them.
+
diff --git a/doc/license.tex b/doc/license.tex
@@ -0,0 +1,29 @@
+\chapter*{License}
+
+This file is distributed under the same terms as wmii:
+
+\begingroup
+\ttfamily
+\parindent=0pt
+\parskip=1em
+
+Copyright © 2009-2010 Kris Maglione <\href{mailto:maglione.k@gmail.com}{maglione.k@gmail.com}>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+\endgroup
diff --git a/doc/wmii.tex b/doc/wmii.tex
@@ -23,6 +23,7 @@
\let\primary=\textbf
\setmainfont[Mapping=tex-text, Numbers=OldStyle]{Palatino LT Std}
+\def\lining{\addfontfeature{Numbers=Lining}}
\let\primary=\textbf
@@ -34,7 +35,7 @@
\makeatletter
%% Key specs
-\def\key#1{{\small$\langle$\addfontfeature{Numbers=Lining}#1\/$\rangle$}}
+\def\key#1{{\small$\langle$\lining#1\/$\rangle$}}
\let\<=<
\catcode`\<=\active
\def<#1>{\key{#1}}
@@ -72,17 +73,14 @@
% Display |...| as verbatim, teletype text.
\DefineShortVerb{\|}
+\def\macroname#1{%
+ \expandafter\@macroname\string#1}
+\def\@macroname#1{}
+\def\defverb#1{%
+ \EA\def\EA#1\EA{\EA\protect\EA\UseVerb\EA{\macroname#1}}%
+ \EA\SaveVerb\EA{\macroname#1}}
+
\let\idx@@heading\chapter
-\def\:{:}
-\iffalse
- \catcode`\:=\active
- \gdef:{\@ifnextchar:{\coloncoloneq}{\:}}
- \gdef\coloncoloneq#1{\@ifnextchar={$\Coloneqq$\coloncoloneqq}{\:\:}}
- \gdef\coloncoloneqq#1{}
-\fi
-\def\≔{≔}
-\catcode`\≔=\active
-\def≔{\ensuremath{\Coloneqq}}
%% Create a verbatim {code} environment which highlights strings
%% and comments. Several unicode characters are hacked to replace
@@ -92,24 +90,30 @@
\colorlet{string}{red!100!black!90}
\let\‘=‘
\let\“=“
-\catcode`¶=6
-\catcode`#=\active\let#=\#
-\catcode`\#=\active
-\catcode`“=\active
-\catcode`‘=\active
-\def“¶1”{{\color{string}\“¶1”}}%
-\def‘¶1’{{\color{string}\‘¶1’}}%
-\def\comment{\itshape\color{comment}\let“=\“\let‘=\‘\#}
-\def\docodes{\catcode`\#=\active\catcode`“=\active\catcode`‘=\active\catcode`\☺=0}
-\def\dodefineactive{
- \let#=\comment
- }
+\def\≔{≔}
+\catcode`#=\active
+\catcode`\≔=\active
+\def\docodes{%
+ \catcode`\#=\active%
+ \catcode`“=\active%
+ \catcode`‘=\active}
+
+\def≔{\ensuremath{\Coloneqq}}
+\let#=\#
+\begingroup
+ \docodes
+ \catcode`\#=\active%
+ \catcode`¶=6
+ \gdef\comment{\itshape\color{comment}\let“=\“\let‘=\‘\#}
+ \gdef\dodefineactive{%
+ \let#=\comment%
+ \gdef“¶¶1”{{\color{string}\“¶¶1”}}%
+ \gdef‘¶¶1’{{\color{string}\‘¶¶1’}}}
+\endgroup
+
\DefineVerbatimEnvironment{code}{Verbatim}{xleftmargin=2em,gobble=2,%
- codes={\docodes},%
+ codes={\docodes\catcode`\☺=0},%
defineactive={\dodefineactive}}
-\catcode`\#=6
-\catcode`“=12
-\catcode`‘=12
%% Save code fragments for piecing together later
\begingroup
@@ -143,7 +147,6 @@
\def\UseFragment#1#2{
\begingroup
- % \message{UseFragment #2^^J}
\EA\let\EA\a\csname SV@#2\endcsname
\ifx\a\undefined\def\a{\ldots}\fi
\ifx\FV@EnvironName\relax%
@@ -152,19 +155,26 @@
\newtoks\tokens
\EA\tokens\EA{\a}
\everyeof{\noexpand}%
- % \EA\message\EA{\the\tokens}
\scantokens\EA{\the\tokens}
\endgroup
}
%% Convenience defs for the various wmii commands, and a few
%% others.
-\def\wmii{\texttt{wmii}}
-\def\wiIXmenu{\texttt{wi9menu}}
-\def\wimenu{\texttt{wimenu}}
-\def\wmiir{\texttt{wmiir}}
-\def\ninep{{\addfontfeature{Numbers=Lining}9P}}
+\defverb\wmii|wmii|
+\defverb\wiIXmenu|wimii9menu|
+\defverb\wimenu|wimenu|
+\defverb\wmiir|wmiir|
+\def\ninep{{\lining 9P}}
\def\POSIX{\textsc{POSIX}}
+\def\plannine{{\lining Plan 9}}
+\def\ICCCM#1{%
+ \@ICCCM#1@
+ \href{http://www.tronche.com/gui/x/icccm/sec-\@ICCCM@chap.html\#s-#1}{%
+ ICCCM \lining§#1}}
+\def\@ICCCM#1.#2@{\def\@ICCCM@chap{#1}}
+
+\makeatother
\begin{document}
\thispagestyle{empty}
@@ -183,7 +193,7 @@
\Large
Kris Maglione \\[1em]
- \addfontfeature{Numbers=Lining}
+ \lining
13 October 2009
\end{center}
@@ -197,1432 +207,14 @@
\tableofcontents
\newpage
-\chapter*{License}
-
-This file is distributed under the same terms as wmii:
-\begingroup
-\ttfamily
-\parindent=0pt
-\parskip=1em
-
-Copyright © 2009 Kris Maglione <\href{mailto:maglione.k@gmail.com}{maglione.k@gmail.com}>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-\endgroup
+\include{license}
\mainmatter
-\chapter{Introduction}
-
-\wmii\ is a simple but powerful window manager for the X Window
-System. It provides both the classic (“floating”) and tiling
-(“managed”) window management paradigms, which is to say, it does
-the job of managing your windows, so you don't have to. It also
-provides programability by means of a simple file-like
-interface, which allows the user to program in virtually any
-language he chooses. These basic features have become
-indispensable to the many users of \wmii\ and other similar
-window managers, but they come at a cost. Though our penchant
-for simplicity makes \wmii's learning curve significantly
-shorter than most of its competitors, there's still a lot to
-learn. The rest of this guide will be devoted to familiarizing
-new users with \wmii's novel features and eccentricities, as
-well as provide advanced users with an in-depth look at our
-customization facilities.
-
-\section{Concepts}
-
-As noted, \wmii\ provides two management styles:
-
-\begin{description}
- \item[Managed] This is the primary style of window management
- in \wmii. Windows managed in this style are automatically
- arranged by \wmii\ into columns. Columns are created and
- destroyed on demand. Individual windows in the column may be
- moved or resized, and are often collapsed or hidden
- entirely. Ad-hoc stacks of collapsed and uncollapsed windows
- allow the user to efficiently manage their tasks. When
- switching from an active to a collapsed window, the active
- window collapses and the collapsed one effectively takes
- its place.
-
- Managed windows have an unadorned titlebar:
-
- \titlebar{managed}
-
- \item[Floating] Since some programs aren't designed in ways
- conducive to the managed work flow, \wmii\ also provides the
- classic “floating” window management model. Windows managed
- in this model float above the managed windows and may be moved
- freely about. Other than automatic placement of new windows
- and snapping of edges, \wmii\ doesn't manage floating
- windows at all.
-
- Floating windows are indicated by a decorated titlebar:
-
- \titlebar{floating}
-
- \item[Fullscreen] Fullscreen mode is actually a subset of the
- floating style. Windows may be toggled to and from
- fullscreen mode at will. When fullscreen, windows reside in
- the floating layer, above the managed windows. They have no
- borders or titlebars, and occupy the full area of the
- screen. Other than that, however, they're not special in any
- way. Other floating windows may appear above them and the
- user can still select, open, and close other windows at
- will.
-\end{description}
-
-\subsection{The Filesystem}
-
-All of \wmii's customization is done via a virtual filesystem.
-Since the filesystem is implemented in the standardized \ninep\
-protocol, it can be accessed in many ways. \wmii\ provides a
-simple command-line client, \wmiir, but many alternatives exist,
-including libraries for Python, Perl, Ruby, PHP, and C. It can
-even be mounted, either by Linux's 9p.ko kernel module or
-indirectly via FUSE.
-
-The filesystem that \wmii\ provides is “virtual”, which is to
-say that it doesn't reside on disk anywhere. In a sense, it's a
-figment of \wmii's imagination. Files, when read, represent
-\wmii's current configuration or state. When written, they
-perform actions, update the UI, etc. For instance, the directory
-|/client/| contains a directory for each window that \wmii\
-is currently managing. Each of those directories, in turn,
-contains files describing the client's properties (its title,
-its views\footnote{Views in \wmii\ are akin to workspaces or
-virtual desktops in other window managers, but with some subtle
-differences.}, its state). Most files can be written to update
-the state they describe. For instance,
-|/client/sel/ctl| describes the state of the selected
-client. If a client is fullscreen, it contains the line:
-
-\begin{code}
- fullscreen on
-\end{code}
-
-\noindent To change this, you'd update the file with the line
-% XXX: Line broken at /ctl cmd.
-|fullscreen off| or even |fullscreen| |toggle| to toggle
-the client's fullscreen state.
-
-The concept of controlling a program via a filesystem derives
-from Plan 9, where such interfaces are extensive and well
-proven\footnote{The concept has also taken hold on most Unixes
-in the form of \texttt{/proc} and \texttt{/sys} virtual
-filesystems, but tends to be very kernel-centric. On Plan 9,
-where the model is more pervasive, there are more virtual
-filesystems for user-level applications than for the kernel.}.
-The metaphor has shown itself to be quite intuitive to Unix
-users, once the shock of a “virtual” filesystem wears off. The
-flexibility of being able to control \wmii\ from myriad
-programming languages, including the standard Unix shell and
-even from the command line, is well worth the shock.
-
-\subsection{Views and Tags}
-
-Like most X11 window managers, \wmii\ provides virtual
-workspaces. Unlike other window managers though, \wmii's
-workspaces are created and destroyed on demand. Instead of being
-sent to a workspace, windows in \wmii\ are tagged with any
-number of names. Views are created dynamically from these tags,
-and automatically if the user tries to access them. For
-instance, if a window is given the tags ‘foo’ and ‘bar’, the two
-views ‘foo’ and ‘bar’ are created, if they don't already exist.
-The window is now visible on both of them. Moreover, tags can be
-specified as regular expressions. So, a client tagged with {\tt
-\verb+/^foo/+} will appear on any view named ‘foo’, ‘foo:bar’,
-and so forth. Any time a client is tagged with a matching tag,
-or the user opens a matching view, the window is automatically
-added to it.
-
-\subsection{The Bar}
-
-\wmii\ provides a general purpose information bar at the top or
-bottom of the screen. The bar is divided into a left and a right
-section. Each section is made up of buttons, with a single
-button spanning the gap between the two sides. Buttons can be
-individually styled and can hold any text content the user
-wishes. By convention, the buttons to the left show view names,
-and those to the right display status information.
-
-\subsection{The Menus}
-
-\wmii\ includes two simple, external menu programs. The first,
-\wimenu, is keyboard-based, and is used to launch programs and
-generally prompt the user for input. It provides a list of
-completions which are automatically filtered as you type. The
-second, \wiIXmenu, is mouse-based, and is generally used to
-provide context menus for titlebars and view buttons. Both menus
-can be easily launched from shell scripts or the command line,
-as well as from more complex scripting languages.
-
-\subsection{The Keyboard}
-
-\wmii\ is a very keyboard friendly window manager. Most actions
-can be performed without touching the mouse, including
-launching, closing, moving, resizing, and selecting programs.
-New keybindings of any complexity can easily be added to handle
-any missing functionality, or to simplify any repetitive tasks.
-
-\subsection{The Mouse}
-
-Despite being highly keyboard-accessible, \wmii\ strives to be
-highly mouse accessible as well. Windows can be moved or resized
-by dragging their window borders. When combined with a key
-press, they can be moved, resized, or raised by dragging any
-visible portion of the window. Mouse menus are accessed with a
-single click and drag. View buttons in the bar and client
-titlebars respond to the mouse wheel; view buttons can be
-activated by dragging any draggable object (e.g., a file from a
-file manager) over them.
-
-\chapter{Getting Started}
-
-This section will walk you through your first \wmii\ startup.
-For your first experience, we recommend running \wmii\ in its
-own X session, so you can easily switch back to a more
-comfortable environment if you get lost. Though you may start
-\wmii\ from a session manager in your day to day use, these
-instructions will use |xinit|. To begin with, copy this file
-to your home directory, so we can open it in your new X session.
-Then setup your |~/.xinitrc| as follows:
-
-\begin{code}
- cd
-
- # Start a PDF viewer with this guide. Use any viewer
- # you're comfortable with.
- xpdf wmii.pdf &
-
- # Launch wmii
- exec wmii
-
- # That was easy.
-\end{code}
-
-Before you run |xinit|, make sure you know how to switch
-between terminals. Depending on your system, your current X
-session is probably on terminal 5 or 7. You should be able to
-switch between your terminals by pressing
-Ctrl-Alt-F$\langle n\rangle$. Assuming that your current X
-session is on terminal 7, you should be able to switch between
-it and your new session by pressing Ctrl-Alt-F7 and Ctrl-Alt-F8.
-Now you should be ready to start \wmii. When you run the
-following command, you should be presented with a new X session
-running wmii and a PDF viewer showing this document.
-
-\begin{code}
- xinit
-\end{code}
-
-When you're there, find this page in the new PDF viewer and
-continue.
-
-\section{Your First Steps}
-
-If everything went according to plan, you should be viewing this
-from a nearly empty \wmii\ session. We're going to be using the
-keyboard a lot, so let's start with a convention for key
-notation. We'll be using the key modifiers Control, Alt, Shift,
-and Meta\footnote{The Windows$^{\mbox{\tiny®}}$ key on most
-keyboards. The Penguin key, on the more tongue in cheek
-varieties.}, which we'll specify as C-, A-, S-, and M-,
-respectively. So, <C-S-a> means pressing ‘|a|’ while holding
-|Control| and |Shift|. We'll also express mouse clicks this
-way, with <M-Mouse1> signifying a press of the right mouse
-button, with the Meta key depressed. Buttons 4 and 5 are the up
-and down scroll wheel directions, respectively.
-
-\subsection{Floating Mode}
-
-Beginning with what's familiar to most users, we'll first explore
-floating mode. First, we need to select the floating layer.
-Press <M-Space>. You should see the titlebar of this window
-change color. Now, press <M-Return> to launch a terminal.
-The easiest way to drag the terminal around is to press and hold
-<M-Mouse1> over the window and simply drag the window
-around. You should be able to drag the window anywhere onscreen
-without ever releasing the mouse button. As you drag near the
-screen edges, you should notice a snap. If you try to drag the
-window fully off-screen, you'll find it constrained so that a
-portion always remains visible. Now, release the window and move
-the mouse toward one of its corners. Press and hold
-<M-Mouse3>\footnote{The right button.}. As you drag the
-mouse around, you should see the window resized accordingly.
-
-To move the window without the modifier key, move the pointer
-over the layout box to the left of its titlebar. You should see
-the cursor change. Now, simply click and drag. To resize it,
-move the pointer toward the window's edge until you see the
-cursor change, and again, click and drag. Now, to close the
-window, move the mouse over the windows titlebar, press and hold
-<Mouse3>, select |Delete|, and release it. You should
-see this window's titlebar return to its original color,
-indicating that it's regained focus.
-
-\subsection{Managed Mode}
-
-Now, for the fun part. We'll start exploring managed mode by
-looking at the basics of columns. In the default configuration,
-columns have three modes:
-
-\begin{description}
- \item[Stack] <M-s> The default mode for new columns. Only one window
- is fully visible per column at once. The others only display
- their title bars. When new windows are added to the column,
- the active window collapses, and the new one takes its
- place. Whenever a collapsed client is selected, the active
- window is collapsed to take its place.
- \item[Max] <M-m> Like stack mode, but the titlebars of collapsed
- clients are hidden.
- \item[Default] <M-d> Multiple uncollapsed windows may be visible at
- once. New windows split the space with the other uncollapsed
- windows in their vicinity. Windows may still be collapsed by
- shrinking them to the size of their titlebars. At this
- point, the behavior of a stack of collapsed and uncollapsed
- clients is similar to that of stack mode.
-\end{description}
-
-Before we open any new windows in managed mode, we need to
-explore the column modes a bit. Column modes are activated with
-the key bindings listed above. This column should be in stack
-mode now. Watch the right side of the titlebar as you press
-<M-m> to enter max mode. You should see an indicator appear.
-This tells you the number of hidden windows directly above and
-below the current window, and its position in that stack. Press
-<M-d> to enter default mode. Now we're ready to open another
-client. Press <M-Return> to launch another terminal. Now,
-press <M-S-l> to move the terminal to a new column to the
-right of this one. Once it's there, press <M-Return> two
-more times to launch two more terminals. Now that you have more
-than one window in a column, cycle through the three column
-modes again until they seem familiar.
-
-\subsection{Keyboard Navigation}
-
-To begin, switch back to default mode. The basic keyboard
-navigation keys, <M-h>, <M-j>, <M-k>, and <M-l>,
-derive from vi, and represent moving left, down, up, and right
-respectively. Try selecting each of the four windows currently
-visible on screen. Notice that navigation wraps from one side of
-the screen to the other, and from the top to the bottom. Now,
-return to the write column, switch to stack mode, and select
-each of the three terminals again. Do the same in max mode,
-paying careful attention to the indicator to the right of the
-titlebar.
-
-Now that you can select windows, you'll want to move them
-around. To move a window, just add the Shift key to the
-direction keys. So, to move a window left, instead of <M-h>,
-type <M-S-h>. Now, experiment with moving windows, just as
-you did with navigating them, in each of the three column modes.
-Once you're comfortable with that, move a window to the floating
-layer. Since we toggled between the floating and managed layers
-with <M-Space>, we'll move windows between them with
-<M-S-Space>. Try moving some windows back and forth until it
-becomes familiar. Now, move several windows to the floating
-layer and try switching between them with the keyboard. You'll
-notice that <M-h> and <M-l> don't function in the
-floating layer. This is for both historical and logistical
-reasons. <M-j> and <M-k> cycle through floating windows
-in order of their most recent use.
-
-\subsection{Mouse Navigation}
-
-\wmii\ uses the “sloppy focus” model, which is to say, it focuses
-windows when the mouse enters them and when you click them. It
-focuses windows only when you select them with the keyboard,
-click their titlebars, or press click them with <M-Mouse2>.
-Collapsed windows may be opened with the mouse by clicking their
-titlebars. Moving and resizing floating windows should be
-largely familiar, and has already been covered. The same can't
-be said for managed windows.
-
-Let's begin working with the mouse in the managed layer. Return
-to a layout with this document in a column on the left, and
-three terminals in a column to the right. Switch the right
-column to default mode. Now, bring the mouse to the top of the
-third terminal's titlebar until you see a resize cursor. Click
-and drag the titlebar to the very top of the screen. Now, move
-the cursor to the top of the second terminal's titlebar and drag
-it to the very bottom of the screen. Press <M-d> to restore the
-terminals to their original sizes. Now, click and hold the
-layout box of the second terminal. Drag it to the middle of the
-terminal's window and release. Click and hold the layout box of
-the third terminal and drag it to the middle of the first
-terminal's window. Finally, drag the first terminal's layout box
-to halfway down this window. <M-Mouse1> works to the same
-effect as dragging the layout box, but allows you to click
-anywhere in the window.
-
-Now that you've seen the basics of moving and dragging windows,
-let's move on to columns. Click and drag the border between the
-two columns. If that's a difficult target to click, there's a
-triangle at the top of the division between the two columns that
-you can click and drag as well. If that's still too hard a
-target, try using <M-Mouse3>, which works anywhere and provides
-much richer functionality.
-
-\subsection{Window Focus and Selection}
-
-For the purposes of keyboard navigation, \wmii\ keeps track of
-which window is currently selected, and confers its titlebar a
-different color scheme from the other windows. This window is
-the basis of relative motion commands, such as “select the
-window to the left”, and the target of commands such as “close
-this window”. Normally, the selected window is the same as the
-focused window, i.e., the window that receives keyboard events.
-Some applications, however, present strange corner cases.
-
-\begin{description}
- \item[Focused, selected window] This is the normal case of a
- window which is both selected and has the keyboard focus.
- \titlebar{selected}
- \item[Unfocused, unselected window] This is the normal case for an
- unselected window which does not have the keyboard focus.
- \titlebar{unselected}
- \item[Unfocused, selected window] This is the first unusual
- case. This is the selected window, for the purposes of
- keyboard navigation, but it does not receive keyboard events.
- A good example is an onscreen keyboard, which will receive
- mouse clicks and translate them to keyboard events, but
- won't absorb those keyboard events itself. Other examples
- include any window whilst another (such as \wimenu) has
- grabbed the keyboard.
- \titlebar{unfocused}
- \item[Focused, unselected window] This is the second unusual
- focus case. The window has the keyboard focus, but for the
- purposes of keyboard navigation, it is not considered
- selected. In the case of an onscreen keyboard, this is the
- window which will receive the generated events. In the case
- of a keyboard grab, the will likely be the window holding
- the grab.
- \titlebar{focused}
-\end{description}
-
-\section{Running Programs}
-
-You've already seen the convenient key binding to launch a
-terminal, but what about other programs? To get a menu of all of
-the executables in your path, type <M-p>. This should replace
-the bar at the bottom of the screen with a prompt, followed by a
-string of completions. Start typing the name of a program that
-you want to open. You can press <Tab> and <S-Tab> to cycle
-through the completions, or you can just press <Return> to
-select the first one. If you want to execute a more complex
-command, just type it out and press <Return>. If you want to
-recall that command later, use \wimenu's history. Start typing
-the command you want and then press <C-p> until you come to it.
-
-When you're done with a program, you'll probably want an easy
-way to close it. The first way is to ask the program to close
-itself. Since that can be tedious (and sometimes impossible),
-\wmii\ provides other ways. As mentioned, you can right click
-the titlebar and select |Delete|. If you're at the keyboard,
-you can type <M-S-c>. These two actions cause \wmii\ to ask
-nicely that the program exit. In those sticky cases where the
-program doesn't respond, \wmii\ will wait 10 seconds before
-prompting you to kill the program. If you don't feel like
-waiting, you can select |Kill| from the window's titlebar
-menu, in which case \wmii\ will forcefully and immediately kill
-it. Beware, killing clients is a last resort. In cases where the
-same program opens multiple windows, killing one will kill them
-all—without warning.
-
-\section{Using Views}
-
-As already noticed, \wmii's concept of virtual workspaces is
-somewhat unique, so let's begin exploring it. Open up a terminal
-and press <M-S-2>. You should see a new button on the bar at the
-bottom of the screen. When you click it, you should see your
-original terminal. Press <M-1> to come back here. Now, press
-<M-3>, and <M-1> again to return here once more. Notice that the
-views were created when needed, and destroyed when no longer
-necessary. If you want to select a view with a proper name, use
-<M-t> and enter the name. Other than the dynamic creation of
-views, this is still similar to the familiar X11 workspace
-model. But that's just the beginning of \wmii's model. Open a new
-terminal, and type:
-
-\begin{code}
- echo ‘Hello world!’
-\end{code}
-
-\noindent Now, type <M-S-t>. In the menu that appears, enter
-|1+2+3|. Now, visit the views |1|, |2|, and |3|, and you'll see
-the client on each. To remove a tag, type <M-S-t> again, and
-this time enter |-2|. You'll notice that the client is no longer
-on the |2| view. Finally, tag names needn't be discrete,
-ordinary strings. They can also be regular expressions. Select
-the terminal again, and enter |+/^5/|. Now, switch to the |5|
-view. Now try the |6| view. Finally, type <M-t> and enter |50|
-to check the |50| view. Clients tagged with regular expressions
-are attached to any matching views when they're created. So,
-when you switch to an empty view, or tag a client with a new
-tag, any clients with matching regular expressions are
-automatically added to it. When all explicitly tagged clients
-disappear from the view, and it's no longer visible, clients
-held there by regular expressions are automatically removed.
-
-\section{Learning More}
-
-For full tables of the standard key bindings, and descriptions
-of the precise semantics of the topics discussed above, you
-should refer to \wmii's |man| pages.
-
-\chapter{Customizing \wmii}
-
-There are several configuration schemes available for \wmii. If
-you're only looking to add basic key bindings, status monitors,
-\emph{et cetera}, you should have no trouble modifying the stock
-configuration for your language of choice. If you're looking for
-deeper knowledge of \wmii's control interface though, this
-section is for you. We'll proceed by building a configuration
-script in \POSIX\ |sh| syntax and then move on to a discussion
-of the higher level constructs in the stock configuration
-scripts.
-
-\section{Events}
-
-The \wmii\ control interface is largely event driven. Each event
-is represented by a single, plain-text line written to the
-|/event| file. You can think of this file as a named pipe. When
-reading it, you won't receive an EOF\footnote{End of File} until
-\wmii\ exits. Moreover, any lines written to the file will be
-transmitted to everyone currently reading from it. Notable
-events include key presses, the creation and destruction of
-windows, and changes of focus and views.
-
-We'll start building our configuration with an event processing
-framework:
-
-\begin{Fragment}{Event Loop}
- # Broadcast a custom event
- wmiir xwrite /event Start wmiirc
-
- # Turn off globbing
- set -f
- # Open /event for reading
- wmiir read /event |
- # Read the events line by line
- while read line; do
- # Split the line into words, store in $@
- set -- $line
- event=$1; shift
- line = "$(echo $line | sed ‘s/^[^ ]* //’ | tr -d ‘\n’)"
- # Process the event
- case $event in
- Start) # Quit when a new instance starts
- [ $1 = wmiirc ] && exit;;
- «Event Handlers»
- esac
- done
-\end{Fragment}
-
-Now, we need to consider which types of events we'll need to
-handle:
-
-\begin{Fragment}{Event Handlers}
- «View Button Events»
- «Urgency Events»
- «Unresponsive Clients»
- «Notice Events»
- «Key Events»
- «Client Menu Events»
- «Tag Menu Events»
-\end{Fragment}
-
-\section{Bar Items}
-
-The bar is described by the files in the two directories |/lbar/| and
-|/rbar/| for buttons on the left and right side of the bar,
-respectively. The files act as control files (section
-\ref{sec:controlfiles}) with the contents:
-
-\begin{code}
- color ‹Color Tuple›
- label ‹Label›
-\end{code}
-
-A ‹Color Tuple› is defined as:
-
-\begin{code}
- ‹Color Tuple› ≔ ‹foreground color› ‹background color› ‹border color›
- ‹* Color› ≔ ‹RGB color› | ‹RGBA color›
- ‹RGB color› ≔ #‹6 character RGB hex color code›
- ‹RGBA color› ≔ rgba:‹red›/‹green›/‹blue›/‹alpha›
-\end{code}
-
-\noindent
-where all of the colors are represented as lowercase,
-hexidecimal values. In the case of RGBA colors, they may be 1--4
-characters long, though they will be standardized internally to
-2 characters.
-
-\medskip
-
-Let's define our basic theme information now:
-
-\begin{Fragment}{Theme Definitions}
- normcolors=‘#000000 #c1c48b #81654f’
- focuscolors=‘#000000 #81654f #000000’
- background=‘#333333’
- font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*’
-\end{Fragment}
-
-\subsection{View Buttons}
-
-With a basic understanding of bar items in mind, we can write
-our view event handlers:
-
-\index{events!CreateTag}
-\index{events!DestroyTag}
-\index{events!FocusTag}
-\index{events!UnfocusTag}
-\begin{Fragment}{View Button Events}
- CreateTag) # CreateTag ‹Tag Name›
- echo $normcolors $1 | wmiir create /lbar/$1;;
- DestroyTag) # DestroyTag ‹Tag Name›
- wmiir rm /lbar/$1;;
- FocusTag) # FocusTag ‹Tag Name›
- wmiir xwrite /lbar/$1 $focuscolors $1;;
- UnfocusTag) # UnfocusTag ‹Tag Name›
- wmiir xwrite /lbar/$1 $normcolors $1;;
-\end{Fragment}
-
-\subsection{Urgency}
-
-\index{events!UrgentTag|(}
-\index{events!NotUrgentTag|(}
-Windows can specify that they require attention, and in X11
-parlance, this is called urgency. When a window requests
-attention as such, or declares that it's been satisfied, \wmii\
-broadcasts an event for the client and an event for each view
-that it belongs to. It also fills in the layout box of any
-client deemed urgent. It's the job of a script to decide how to
-handle urgency events above and beyond that basic measure. The
-standard scripts simply mark urgent views with an asterisk:
-
-\begin{Fragment}{Urgency Events}
- # The urgency events are ‘Client’ events when the program
- # owning the window sets its urgency state. They're ‘Manager’
- # events when wmii or the wmii user sets the state.
- UrgentTag) # UrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
- wmiir xwrite /lbar/$2 $2;;
- NotUrgentTag) # NotUrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
- wmiir xwrite /lbar/$2 $2;;
-\end{Fragment}
-\index{events!UrgentTag|)}
-\index{events!NotUrgentTag|)}
-
-\subsection{Notices}
-
-The standard scripts provide a custom Notice event for
-displaying status information. The events appear in the long bar
-between the left and right sides for five seconds.
-
-\begin{Fragment}{Notice Events}
- Notice)
- wmiir xwrite /rbar/!notice $line
- kill $xpid 2>/dev/null # Let's hope this isn't reused...
- { sleep 5; wmiir xwrite /rbar/!notice ‘ ’; } &
- xpid = $!;;
-\end{Fragment}
-
-\section{Keys}
-
-\label{sec:keybindings}
-\index{key bindings}
-\index{filesystem!/!keys}
-\index{filesystem!/!event}
-Now to the part you've no doubt been waiting for: binding keys.
-When binding keys, you need to be aware of two files, |/keys|
-and |/event|. The former defines which keys \wmii\ needs to
-grab, and the latter broadcasts the events when they're pressed.
-
-Key names are specified as a series of modifiers followed by a
-key name, all separated by hyphens. Valid modifier names are
-|Control|, |Shift|, |Mod1| (usually Alt), |Mod2|, |Mod3|, |Mod4|
-(usually the Windows® key), and |Mod5|. Modifier keys can be
-changed via |xmodmap(1)|, the details of which are beyond the
-scope of this document.
-
-Key names can be detected by running |xev| from a
-terminal, pressing the desired key, and looking at the output
-(it's in the parentheses, after the keysym). Or, more simply,
-you can run the \man 1 {wikeyname} utility bundled with \wmii\
-and press the key you wish to bind.
-
-Examples of key bindings:
-
-\begin{description}
- \item[Windows® key + Capital A] |Mod4-Shift-A|
- \item[Control + Alt + Space] |Mod1-Control-Space|
-\end{description}
-
-Now, let's bind the keys we plan on using:
-
-\begin{Fragment}{Bind Keys}
- {
- cat <<!
- Mod4-space
- Mod4-d
- Mod4-s
- Mod4-m
- Mod4-a
- Mod4-p
- Mod4-t
- Mod4-Return
- Mod4-Shift-space
- Mod4-f
- Mod4-Shift-c
- Mod4-Shift-t
- Mod4-h
- Mod4-j
- Mod4-k
- Mod4-l
- Mod4-Shift-h
- Mod4-Shift-j
- Mod4-Shift-k
- Mod4-Shift-l
- !
- for i in 1 2 3 4 5 6 7 8 9 0; do
- echo Mod4-$i
- echo Mod4-Shift-$i
- done
- } | wmiir write /keys
-\end{Fragment}
-
-and lay a framework for processing their events:
-
-\begin{Fragment}{Key Events}
- Key) # Key ‹Key Name›
- case $1 in
- «Motion Keys»
- «Client Movement Keys»
- «Column Mode Keys»
- «Client Command Keys»
- «Command Execution Keys»
- «Tag Selection Keys»
- «Tagging Keys»
- esac;;
-\end{Fragment}
-
-\section{Click Menus}
-
-Sometimes, you have your hand on the mouse and don't want to
-reach for the keyboard. To help cope, \wmii\ provides a
-mouse-driven, single-click menu. The default configuration uses
-it for client and tag menus.
-
-\begin{Fragment}{Click Menu Initialization}
- clickmenu() {
- if res=$(wmii9menu -- “$@”); then eval “$res”; fi
- }
-\end{Fragment}
-
-\section{Control Files}
-
-\label{sec:controlfiles}
-
-Several directories including the root, have control files,
-named |ctl|. These files are used to control the object (e.g., a
-client or tag) represented by the directory. Each line of the
-file, with the possible section of the first, represents a
-control variable and its value. In the case of all but the root
-|/ctl| file, the first line represents the id of the directory.
-In the case of |/tag/foo/ctl|, for instance, the first line
-should read |foo|. This is useful when dealing with the special
-|sel/| directories. For instance, when |foo| is the selected
-tag, the special |/tag/sel| directory is a link to |/tag/foo|,
-and the first line of |/tag/sel/ctl| will read |foo|, just as
-if you'd accessed |/tag/foo/ctl| directly.
-
-The rest of the lines, the control variables, can be modified by
-writing new values to the control file. For instance, if a
-client is fullscreen, its control file will contain the line:
-
-\begin{code}
- fullscreen on
-\end{code}
-
-\noindent To restore the client from fullscreen, either of the
-following lines may be written to its control file:
-
-\begin{code}
- fullscreen off
- fullscreen toggle
-\end{code}
-
-When next read, the |fullscreen on| line will have been replaced
-with |fullscreen off|. No care need be taken to preserve the
-other contents of the file. They're generated anew each time
-it's read.
-
-\section{Clients}
-
-\def\clientlabel{/client/$\langle\mathit{client}\rangle$/}
-\index{filesystem!/client/*/@\clientlabel|(}
-Clients are represented by directories under the |/client/|
-tree. Subdirectory names represent the client's X11 window ID.
-The special |sel/| directory represents the currently selected
-client. The files in these directories are:
-
-\begin{description}
- \item[ctl] The control file. The properties are:
- \index{filesystem!/client/*/@\clientlabel!ctl}
- \begin{description}
- \item[allow] The set of unusual actions the client is
- allowed to perform, in the same format as the tag set.
- \begin{description}
- \item[activate] The client is allowed to activate
- itself—that is, focus its window and, as the case may
- require, uncollapse it and select a tag it resides on.
- This flag must be set on a client if you wish it able to
- activate itself from the system tray.
- \end{description}
- \item[floating] Defines whether this client is likely to
- float when attached to a new view. May be |on|, |off|,
- |always|, or |never|. Ordinarilly, the value changes
- automatically whenever the window is moved between the
- floating and managed layers. However, setting a value of
- |always| or |never| overrides this behavior.
- \item[fullscreen] The client's fullscreen state. When
- |on|, the client is displayed fullscreen on all of its
- views. Possible values are |on|, |off|, and |toggle|.
- \item[group] The client's group ID, or 0 if not part of a
- group. Clients tend to open with the same tags and in
- the same columns as the last active member of their
- group. Setting this property is only useful when done
- via the rules file.
- \item[kill] When written, the window is closed politely,
- if possible.
- \item[pid] Read-only value of the PID of the program that
- owns the window, if the value is available and the
- process is on the same machine as wmii.
- \item[slay] When written, the client is disconnected
- peremptorily. If the client's PID is available and the
- process is the same machine as wmii, its parent process
- is killed
- \item[tags] The client's tags. The same as the tags file.
- \item[urgent] The client's urgency state. When |on|, the
- client's layout box will be highlighted. Possible values
- are |on|, |off|, and |toggle|.
- \end{description}
- \item[props] The client's window class (the X11 |WM_CLASS|
- property) and title string, separated by colons. This file
- is not writable.
- \index{filesystem!/client/*/@\clientlabel!props}
- \item[label] The client's window title. May be written to
- change the client's title.
- \index{filesystem!/client/*/@\clientlabel!label}
- \item[tags]
- \index{filesystem!/client/*/@\clientlabel!tags}
- The client's tags. Tag names are separated by |+|, |-|, or
- |^| signs. Tag names which directly follow a |+| sign are
- added, while whose following a |-| sign are removed and
- those following a |^| are toggled. If the value written
- begins with one of these characters, the value is appended
- to the clients tags rather than replacing them.
-
- Tags formatted as |/‹regex›/| are treated as regular
- expressions, which place the client on any extant matching
- tag\footnote{While a client with a regex tag will always
- appear in all matching views, it will not keep those views
- in existence. When the last client explicitly tagged with a
- view is removed, the view is deleted as soon as it becomes
- inactive.}. Regular expression tags which directly follow a
- minus sign are treated as exclusion expressions. For
- example, the tag string |+/foo/-/food/| will match the tag
- |foobar|, but not the tag |foodstand|.
-\end{description}
-
-\index{filesystem!/client/*/@\clientlabel|)}
-
-\subsection{Key Bindings}
-
-To control clients, we'll add the following key bindings:
-
-\begin{Fragment}{Client Command Keys}
- Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
- Mod4-f) wmiir xwrite /client/sel/ctl Fullscreen toggle;;
-\end{Fragment}
-
-And to manage their tags, we'll need:
-
-\begin{Fragment}{Tagging Keys}
- Mod4-Shift-t)
- # Get the selected client's id
- c=$(wmiir read /client/sel/ctl | sed 1q)
- # Prompt the user for new tags
- tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
- # Write them to the client
- wmiir xwrite /client/$c/tags $tag;;
- Mod4-Shift-[0-9])
- wmiir xwrite /client/sel/tags ${1##*-};;
-\end{Fragment}
-
-\subsection{Click Menus}
-
-\index{events!ClientMouseDown}
-\begin{Fragment}{Client Menu Events}
- ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
- [ $2 = 3 ] && clickmenu \
- “Delete:wmiir xwrite /client/$1/ctl kill” \
- “Kill: wmiirxwrite /client/$1/ctl slay” \
- “Fullscreen:wmiir xwrite /client/$1/ctl fullscreen on”
-\end{Fragment}
-
-\subsection{Unresponsive Clients}
-
-\index{events!UnresponsiveClient|(}
-When \wmii\ tries to close a window, it waits 8 seconds for the
-client to respond, and then lets its scripts decide what to do
-with it. The stock scripts prompt the user for input:
-
-\begin{Fragment}{Unresponsive Clients}
- UnresponsiveClient) # UnresponsiveClient ‹Client ID›
- {
- # Use wihack to make the xmessage a transient window of
- # the problem client. This will force it to open in the
- # floaing layer of whatever views the client is attached to
- resp=$(wihack -transient $1 \
- xmessage -nearmouse -buttons Kill,Wait -print \
- “The following client is not responding.” \
- “What would you like to do?$(echo)” \
- $(wmiir read /client/$1/label))
- [ $resp = Kill ] && wmiir xwrite /client/$1/ctl slay
- } &;;
-\end{Fragment}
-\index{events!UnresponsiveClient|)}
-
-\section{Views}
-
-\def\taglabel{/tag/$\langle\mathit{tag}\rangle$/}
-\index{filesystem!/tag/*/@\taglabel|(}
-Views are represented by directories under the |/tag/| tree. The
-special |sel/| directory represents the currently selected
-client. The |sel| tag is treated similarly elsewhere. The files
-in these directories are:
-
-\begin{description}
- \item[ctl]
- The view's control file. The properties are:
- \index{filesystem!/tag/*/@\taglabel!ctl|(}
- \begin{description}
- \item[select ‹Area›] Select the column ‹Area›, where
- ‹Area› is a 1-based column index, or |~| for the floating
- area. It may be optionally preceded by ‹Screen›|:|, where
- ‹Screen› is a 0-based Xinerama screen index, or “sel”. When
- omitted, ‹Screen› defaults to 0, the primary screen.
- \item[select ‹Area› ‹Client Index›] Select the column ‹Area›, and
- the ‹Client Index›th client.
- \item[select client ‹Client ID›] Select the client with the
- X11 window ID ‹Client ID›.
- \item[select ‹Direction›]
- Select the client in ‹Direction› where ‹Direction› may be
- one of ‹up $\wedge$ down $\wedge$ left $\wedge$ right›.
- \item[send client ‹Client ID› ‹Area›] Send ‹Client ID› to
- ‹Area›. ‹Area› may be |sel| for the selected area, and
- |client ‹Client ID›| may be |sel| for the currently selected
- client.
- \item[send client ‹Client ID› ‹Direction›]
- Send ‹Client ID› to a column or position in its column in
- the given direction.
- \item[send client ‹Client ID› toggle] If ‹Client ID› is
- floating, send it to the managed layer. If it's managed,
- send it to the floating layer.
- \item[swap client ‹Client ID› \ldots] The same as the |send|
- commands, but swap ‹Client ID› with the client at the given
- location.
- \item[colmode ‹Area› ‹Mode›] Set ‹Area›'s mode to ‹Mode›,
- where ‹Mode› is a string of values similar to tag
- specifications. Values which may be added and removed are as
- follows for managed areas:
-
- \begin{description}
- \item[stack] One and only one client in the area is
- uncollapsed at any given time. When a new client is
- selected, it is uncollapsed and the previously selected
- client is collapsed.
- \item[max] Collapsed clients are hidden from view
- entirely. Uncollapsed clients display an indicator
- {\it‹n›/‹m›}, where ‹m› is the number of collapsed
- clients directly above and below the client, plus one,
- and ‹n› is the client's index in the stack.
- \item[default] Like subtracting the stack mode, but all
- clients in the column are given equal height.
- \end{description}
-
- For the floating area, the values are the same, except that
- in |max| mode, floating clients are hidden when the managed
- layer is selected.
- \item[grow ‹Frame› ‹Direction› {[‹Amount›]}] Grow ‹Frame› in
- the given direction, by ‹Amount›. ‹Amount› may be any
- integer, positive or negative. If suffixed with |px|,
- it specifies an exact pixel amount, otherwise it specifies a
- “reasonable increment”. Defaults to 1.
-
- ‹Frame› may be one of:
- \begin{itemize}
- \item client ‹Client ID›
- \item ‹Area› ‹Client Index›
- \end{itemize}
- \item[nudge ‹Frame› ‹Direction› {[‹Amount›]}] Like
- |grow|, but move the client in ‹Direction› instead of
- resizing it.
- \end{description}
- \index{filesystem!/tag/*/@\taglabel!ctl|)}
-\end{description}
-
-\index{filesystem!/tag/*/@\taglabel|)}
-
-\subsection{Key Bindings}
-
-We'll use the following key bindings to interact with views:
-
-\begin{Fragment}{Motion Keys}
- Mod4-h) wmiir xwrite /tag/sel/ctl select left;;
- Mod4-l) wmiir xwrite /tag/sel/ctl select right;;
- Mod4-k) wmiir xwrite /tag/sel/ctl select up;;
- Mod4-j) wmiir xwrite /tag/sel/ctl select down;;
- Mod4-space) wmiir xwrite /tag/sel/ctl select toggle;;
-\end{Fragment}
-
-\begin{Fragment}{Client Movement Keys}
- Mod4-Shift-h) wmiir xwrite /tag/sel/ctl send sel left;;
- Mod4-Shift-l) wmiir xwrite /tag/sel/ctl send sel right;;
- Mod4-Shift-k) wmiir xwrite /tag/sel/ctl send sel up;;
- Mod4-Shift-j) wmiir xwrite /tag/sel/ctl send sel down;;
- Mod4-Shift-space) wmiir xwrite /tag/sel/ctl send sel toggle;;
-\end{Fragment}
-
-\begin{Fragment}{Column Mode Keys}
- Mod4-d) wmiir xwrite /tag/sel/ctl colmode sel -stack-max;;
- Mod4-s) wmiir xwrite /tag/sel/ctl colmode sel stack-max;;
- Mod4-m) wmiir xwrite /tag/sel/ctl colmode sel stack+max;;
-\end{Fragment}
-
-\subsection{Click Menus}
-
-\index{events!LeftBarMouseDown}
-\begin{Fragment}{Tag Menu Events}
- LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
- [ $1 = 3 ] && clickmenu \
- “Delete:delete_view $2”
-\end{Fragment}
-
-\section{Command and Program Execution}
-
-Perhaps the most important function we need to provide for is
-the execution of programs. Since \wmii\ users tend to use
-terminals often, we'll add a direct shortcut to launch one.
-Aside from that, we'll add a menu to launch arbitrary programs
-(with completions) and a separate menu to launch wmii specific
-commands.
-
-We use |wmiir setsid| to launch programs with their own session
-IDs to prevent untoward effects when this script dies.
-
-\begin{Fragment}{Command Execution Initialization}
- terminal() { wmiir setsid xterm “$@” }
- proglist() {
- IFS=:
- wmiir proglist $1 | sort | uniq
- unset IFS
- }
-\end{Fragment}
-
-\subsection{Key Bindings}
-\begin{Fragment}{Command Execution Keys}
- Mod4-Return) terminal & ;;
- Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
- Mod4-a) {
- set -- $(proglist $WMII_CONFPATH | wimenu)
- which=$(which which)
- prog=$(PATH=$WMII_CONFPATH $which $1); shift
- eval exec $prog “$@”
- } &;;
-\end{Fragment}
-
-\section{The Root}
-
-The root filesystem contains the following:
-
-\index{!filesystem!/|(}
-\begin{description}
- \item[ctl] The control file. The properties are:
- \index{filesystem!/!ctl}
- \begin{description}
- \item[bar on ‹top $\wedge$ bottom›] Controls where the bar
- is shown.
- \item[bar off] Disables the bar entirely.
- \item[border] The border width, in pixels, of floating
- clients.
- \item[colmode ‹Mode›] The default column mode for newly
- created columns.
- \item[focuscolors ‹Color Tuple›] The colors of focused
- clients.
- \item[normcolors ‹Color Tuple›] The colors of unfocused
- clients and the default color of bar buttons.
- \item[font ‹Font›] The font used throughout \wmii. If
- prefixed with |xft:|, the Xft font renderer is used, and
- fonts may be antialiased. Xft font names follow the
- fontconfig formula. For instance, 10pt, italic Lucida
- Sans would be specified as
-
- \begin{code}
- xft:Lucida Sans-10:italic
- \end{code}
-
- See \man 1 {fc-match}.
-
- \item[grabmod ‹Modifier Keys›] The key which must be
- pressed to move and resize windows with the mouse
- without clicking hot spots.
- \item[incmode ‹Mode›] Controls how X11 increment hints are
- handled in managed mode. Possible values are:
- \begin{description}
- \item[ignore] Increment hints are ignored entirely.
- Clients are stretched to fill their full allocated
- space.
- \item[show] Gaps are shown around managed client
- windows when their increment hints prevent them from
- filling their entire allocated space.
- \item[squeeze] When increment hints cause gaps to show
- around clients, \wmii\ will try to adjust the sizes
- of the clients in the column to minimize lost space.
- \end{description}
- \item[view ‹Tag›] Change the currently visible view.
- \item[exec ‹Command›] Replaces this \wmii\ instance with
- ‹Command›. ‹Command› is split according to rc quoting
- rules, and no expansion occurs. If the command fails to
- execute, \wmii\ will respawn.
- \item[spawn ‹Command›] Spawns ‹Command› as it would spawn
- |wmiirc| at startup. If ‹Command› is a single argument
- and doesn't begin with |/| or |./|,%
- \hskip 1ex|$WMII_CONF|\-|PATH| is
- searched for the executable. Otherwise, the whole
- argument is passed to the shell for evaluation.
- \end{description}
- \item[keys] The global keybindings. See section \ref{sec:keybindings}.
- \index{filesystem!/!keys|primary}
- \item[event] The global event feed. See section \ref{sec:keybindings}.
- \index{filesystem!/!event|primary}
- \item[colrules]
- \index{filesystem!/!colrules}
- The |/colrules| file contains a list of
- rules which affect the width of newly created columns.
- Rules have the form:
-
- \begin{quote}\texttt{
- /‹regex›/ -> ‹width›{\color{gray}[}+‹width›{\color{gray}]*}}
- \end{quote}
-
- Where,
-
- \begin{code}
- ‹width› ≔ ‹percent of screen› | ‹pixels›px
- \end{code}
-
- When a new column, ‹n›, is created on a view whose name
- matches ‹regex›, it is given the ‹n›th supplied ‹width›.
- If there is no ‹n›th width, it is given
- $1/\mbox{‹ncol›th}$ of the screen.
-
- \item[rules]
- \index{filesystem!/!rules}
- The |/rules| file contains a list of
- rules similar to the colrules. These rules set
- properties for a client when it is created.
- Rules are specified:
-
- \begin{quote}\texttt{
- /‹regex›/ -> ‹key›{\color{gray}=}‹value› {\color{gray}\ldots}}
- \end{quote}
-
- When a client's ‹name›:‹class›:‹title› matches
- ‹regex›, the matching rules are applied. For each
- ‹key›=‹value› pair, the |ctl| file property matching
- ‹key› is set to ‹value›. Additionally, the following
- keys are accepted and have special meaning:
-
- \begin{description}
- \item[continue]
- Normally, when a matching rule is encountered,
- rule matching stops. When the continue key is
- provided (with any value), matching continues at
- the next rule.
- \item[force-tags]
- Like tags, but overrides any settings obtained
- obtained from the client's group or from the
- |_WMII_TAGS| window property.
- \end{description}
-
-\end{description}
-
-\index{!filesystem!/|)}
-
-\subsection{Configuration}
-
-We'll need to let \wmii\ know about our previously defined theme
-information:
-
-\begin{Fragment}{Configuration}
- «Theme Definitions»
-
- xsetroot -solid $background
- wmiir write /ctl <<!
- border 2
- focuscolors $focuscolors
- normcolors $normcolors
- font $font
- grabmod Mod4
- !
-\end{Fragment}
-
-\subsection{Key Bindings}
-
-And we need a few more key bindings to select our views:
-
-\begin{Fragment}{Tag Selection Keys}
- Mod4-t)
- # Prompt the user for a tag
- tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
- # Write it to the filesystem.
- wmiir xwrite /ctl view $tags;;
- Mod4-[0-9])
- wmiir xwrite /ctl view ${1##*-};;
-\end{Fragment}
-
-\section{Tieing it All Together}
-
-\begin{code}
- #!/bin/sh
- «Click Menu Initialization»
- «Command Execution Initialization»
-
- «Configuration»
-
- «Bind Keys»
- «Event Loop»
-\end{code}
-
-\section{The End Result}
-
-For clarity, here is the end result:
-
-\begin{code}
- #!/bin/sh
- # «Click Menu Initialization»
- clickmenu() {
- if res=$(wmii9menu -- “$@”); then eval “$res”; fi
- }
- # «Command Execution Initialization»
- terminal() { wmiir setsid xterm “$@” }
- proglist() {
- IFS=:
- wmiir proglist $1 | sort | uniq
- unset IFS
- }
-
- # «Configuration»
- # «Theme Definitions»
- normcolors=‘#000000 #c1c48b #81654f’
- focuscolors=‘#000000 #81654f #000000’
- background=‘#333333’
- font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*’
-
- xsetroot -solid $background
- wmiir write /ctl <<!
- border 2
- focuscolors $focuscolors
- normcolors $normcolors
- font $font
- grabmod Mod4
- !
-
- # «Bind Keys»
- {
- cat <<!
- Mod4-space
- Mod4-d
- Mod4-s
- Mod4-m
- Mod4-a
- Mod4-p
- Mod4-t
- Mod4-Return
- Mod4-Shift-space
- Mod4-f
- Mod4-Shift-c
- Mod4-Shift-t
- Mod4-h
- Mod4-j
- Mod4-k
- Mod4-l
- Mod4-Shift-h
- Mod4-Shift-j
- Mod4-Shift-k
- Mod4-Shift-l
- !
- for i in 1 2 3 4 5 6 7 8 9 0; do
- echo Mod4-$i
- echo Mod4-Shift-$i
- done
- } | wmiir write /keys
-
- # «Event Loop»
- # Broadcast a custom event
- wmiir xwrite /event Start wmiirc
-
- # Turn off globbing
- set -f
- # Open /event for reading
- wmiir read /event |
- # Read the events line by line
- while read line; do
- # Split the line into words, store in $@
- set -- $line
- event=$1; shift
- line = "$(echo $line | sed ‘s/^[^ ]* //’ | tr -d ‘\n’)"
-
- # Process the event
- case $event in
- Start) # Quit when a new instance starts
- [ $1 = wmiirc ] && exit;;
-
- # «Event Handlers»
- # «View Button Events»
- CreateTag) # CreateTag ‹Tag Name›
- echo $normcolors $1 | wmiir create /lbar/$1;;
- DestroyTag) # DestroyTag ‹Tag Name›
- wmiir rm /lbar/$1;;
- FocusTag) # FocusTag ‹Tag Name›
- wmiir xwrite /lbar/$1 $focuscolors $1;;
- UnfocusTag) # UnfocusTag ‹Tag Name›
- wmiir xwrite /lbar/$1 $normcolors $1;;
-
- # «Urgency Events»
- # The urgency events are ‘Client’ events when the program
- # owning the window sets its urgency state. They're ‘Manager’
- # events when wmii or the wmii user sets the state.
- UrgentTag) # UrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
- wmiir xwrite /lbar/$2 $2;;
- NotUrgentTag) # NotUrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
- wmiir xwrite /lbar/$2 $2;;
-
- # «Unresponsive Clients»
- UnresponsiveClient) # UnresponsiveClient ‹Client ID›
- {
- # Use wihack to make the xmessage a transient window of
- # the problem client. This will force it to open in the
- # floaing layer of whatever views the client is attached to
- resp=$(wihack -transient $1 \
- xmessage -nearmouse -buttons Kill,Wait -print \
- “The following client is not responding.” \
- “What would you like to do?$(echo)” \
- $(wmiir read /client/$1/label))
- [ $resp = Kill ] && wmiir xwrite /client/$1/ctl slay
- } &;;
-
- # «Notice Events»
- Notice)
- wmiir xwrite /rbar/!notice $line
- kill $xpid 2>/dev/null # Let's hope this isn't reused...
- { sleep 5; wmiir xwrite /rbar/!notice ‘ ’; } &
- xpid = $!;;
-
- # «Key Events»
- Key) # Key ‹Key Name›
- case $1 in
- # «Motion Keys»
- Mod4-h) wmiir xwrite /tag/sel/ctl select left;;
- Mod4-l) wmiir xwrite /tag/sel/ctl select right;;
- Mod4-k) wmiir xwrite /tag/sel/ctl select up;;
- Mod4-j) wmiir xwrite /tag/sel/ctl select down;;
- Mod4-space) wmiir xwrite /tag/sel/ctl select toggle;;
-
- # «Client Movement Keys»
- Mod4-Shift-h) wmiir xwrite /tag/sel/ctl send sel left;;
- Mod4-Shift-l) wmiir xwrite /tag/sel/ctl send sel right;;
- Mod4-Shift-k) wmiir xwrite /tag/sel/ctl send sel up;;
- Mod4-Shift-j) wmiir xwrite /tag/sel/ctl send sel down;;
- Mod4-Shift-space) wmiir xwrite /tag/sel/ctl send sel toggle;;
-
- # «Column Mode Keys»
- Mod4-d) wmiir xwrite /tag/sel/ctl colmode sel -stack-max;;
- Mod4-s) wmiir xwrite /tag/sel/ctl colmode sel stack-max;;
- Mod4-m) wmiir xwrite /tag/sel/ctl colmode sel stack+max;;
-
- # «Client Command Keys»
- Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
- Mod4-f) wmiir xwrite /client/sel/ctl fullscreen toggle;;
-
- # «Command Execution Keys»
- Mod4-Return) terminal & ;;
- Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
- Mod4-a) {
- set -- $(proglist $WMII_CONFPATH | wimenu)
- prog=$(PATH=$WMII_CONFPATH which $1); shift
- eval exec $prog “$@”
- } &;;
-
- # «Tag Selection Keys»
- Mod4-t)
- # Prompt the user for a tag
- tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
- # Write it to the filesystem.
- wmiir xwrite /ctl view $tag;;
- Mod4-[0-9])
- wmiir xwrite /ctl view ${1##*-};;
-
- # «Tagging Keys»
- Mod4-Shift-t)
- # Get the selected client's id
- c=$(wmiir read /client/sel/ctl | sed 1q)
- # Prompt the user for new tags
- tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
- # Write them to the client
- wmiir xwrite /client/$c/tags $tag;;
- Mod4-Shift-[0-9])
- wmiir xwrite /client/sel/tags ${1##*-};;
-
- esac;;
-
- # «Client Menu Events»
- ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
- [ $2 = 3 ] && clickmenu \
- “Delete:wmiir xwrite /client/$1/ctl kill” \
- “Kill:wmiir xwrite /client/$1/ctl slay” \
- “Fullscreen:wmiir xwrite /client/$1/ctl fullscreen on”
-
- # «Tag Menu Events»
- LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
- [ $1 = 3 ] && clickmenu \
- “Delete:delete_view $2”
- esac
- done
-\end{code}
+\include{introduction}
+\include{gettingstarted}
+\include{customizing}
\backmatter