summaryrefslogtreecommitdiff
path: root/doc/wmii.tex
blob: 3159d76353ff0fd61cffb361c029b8aafe8f78d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
\documentclass[letterpaper,oneside]{scrbook}

\usepackage{txfonts}

\usepackage{fontspec}
\usepackage{xunicode}
\usepackage{xltxtra}

\usepackage{fancyvrb}
\usepackage[top=1in,bottom=1in]{geometry}
\usepackage{graphicx}
\usepackage{makeidx}
\usepackage{xcolor}
\usepackage[xetex,breaklinks,colorlinks,linkcolor=black]{hyperref}

% Indexes
\makeindex
\let\primary=\textbf

\setmainfont[Mapping=tex-text, Numbers=OldStyle]{Palatino LT Std}

\let\primary=\textbf

\def\titlebar#1{%
  \begin{center}\includegraphics[width=5.5in]{#1.png}\end{center}}

\def\man#1#2{#2\textbf{(#1)}}

% Key specs
\def\key#1{{\small$\langle$\addfontfeature{Numbers=Lining}#1\/$\rangle$}}
\let\<=<
\catcode`\<=\active
\def<#1>{\key{#1}}

% Display ‹...› and «...» as text in left and right pointing
% angle brackets. I use «» and ‹› because my terminal doesn't
% display left and right pointing angle brackets properly, and
% Xorg's compose maps don't provide them, anyway.
\catcode`=\active
\catcode`\‹=\active
\def‹#1›{$\langle${\itshape#1}$\rangle$}
\def«#1»{$\langle\langle${\itshape#1}$\rangle\rangle$}

% Display |...| as verbatim, teletype text.
\DefineShortVerb{\|}

\makeatletter
\let\:=:
\catcode`\:=\active
\def:{\@ifnextchar:{\coloncoloneq}{\:}}
\def\coloncoloneq#1{\@ifnextchar={$\Coloneqq$\coloncoloneqq}{\:\:}}
\def\coloncoloneqq#1{}

% Create a verbatim {code} environment which highlights strings
% and comments. Several unicode characters are hacked to replace
% the grabbed characters, since we can't escape them in the
% verbatim environment.
\colorlet{comment}{gray}
\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’}}%
\DefineVerbatimEnvironment{code}{Verbatim}{xleftmargin=2em,gobble=2,%
  codes={\catcode`\#=\active\catcode`\:=\active\catcode`“=\active\catcode`‘=\active},%
  defineactive={%
    \def#{\itshape\color{comment}\let“=\“\let‘=\‘\#}%
    }}
\catcode`\#=6
\catcode`“=12
\catcode`‘=12

% 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}}
\def\POSIX{\textsc{POSIX}}

\begin{document}
\thispagestyle{empty}
\leavevmode
\vfill

\begin{center}
  \centerline{\includegraphics[width=2in]{../img/wmii.pdf}}

  \vskip 1in

  \LARGE
  The \wmii\ User Guide

  \vskip .5in

  \Large
  Kris Maglione \\[1em]
  \addfontfeature{Numbers=Lining}
  13 October 2009

\end{center}

\vfill

\newpage

\frontmatter

\tableofcontents

\newpage
\chapter*{License}

This file is distributed under the same terms as wmii:

\begingroup
\ttfamily
\parindent=0pt
\parskip=1em

\catcode`\:=12
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

\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: Broken /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. 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{code}
  «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{code}

Now, we need to consider which types of events we'll need to
handle:

\begin{code}
  «Event Handlers» ::=
  «View Button Events»
  «Urgency Events»
  «Unresponsive Clients»
  «Notice Events»
  «Key Events»
  «Client Menu Events»
  «Tag Menu Events»
\end{code}

\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 format of the files is:

\begin{code}
  ‹Color Tuple› ‹Label›
\end{code}

although the color tuple may be elided in cases where the label
doesn't match its format.

A ‹Color Tuple› is defined as:

\begin{code}
  ‹tuple› ::= ‹foreground color› ‹background color› ‹border color›
  ‹color› ::= #‹6 character RGB hex color code›
\end{code}

Let's define our basic theme information now:

\begin{code}
  «Theme Definitions» ::=
  normcolors=‘#000000 #c1c48b #81654f’
  focuscolors=‘#00000081654f #000000
  background=‘#333333
  font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*
\end{code}

\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{code}
  «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{code}

\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, and fills in the client's layout box. It's
the job of a script to decide how to handle it above and beyond
that. The standard scripts simply mark urgent views with an
asterisk:

\begin{code}
  «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{code}
\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{code}
  «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{code}

\section{Keys}

\label{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). A \wmii-specific
utility is forthcoming.

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{code}
  «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{code}

and lay a framework for processing their events:

\begin{code}
  «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{code}

\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{code}
  «Click Menu Initialization» ::=
  clickmenu() {
      if res=$(wmii9menu -- “$@”); then eval “$res”; fi
  }
\end{code}

\section{Control Files}

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[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[Urgent] The client's urgency state. When |on|, the
        client's layout box will be highlighted. Possible values
        are |on|, |off|, and |toggle|.
      \item[kill] When written, the window is closed politely,
        if possible.
      \item[slay] When written, the client is killed peremptorily.
    \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 |+|
    signs. Tags beginning and ending with |/| are treated as
    regular expressions. If the written value begins with a |+|
    or a |-|, the tags are updated rather than overwritten. Tag
    names which directly follow a |-| sign are removed rather
    than added. 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{code}
  «Client Command Keys» ::=
  Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
  Mod4-f) wmiir xwrite /client/sel/ctl Fullscreen toggle;;
\end{code}

And to manage their tags, we'll need:

\begin{code}
  «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{code}

\subsection{Click Menus}

\index{events!ClientMouseDown}
\begin{code}
  «Client Menu Events» ::=
  ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
    [ $2 = 3 ] && clickmenu \
      “Delete:xwrite /client/$1/ctl kill” \
      “Kill:xwrite /client/$1/ctl slay” \
      “Fullscreen:/client/$1/ctl Fullscreen on”
\end{code}

\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{code}
  «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{code}
\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{code}
  «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;;
\end{code}

\subsection{Click Menus}

\index{events!LeftBarMouseDown}
\begin{code}
  «Tag Menu Events» ::=
  LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
    [ $1 = 3 ] && clickmenu \
      “Delete:delete_view $2
\end{code}

\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{code}
  «Command Execution Initialization» ::=
  terminal() { wmiir setsid xterm “$@” }
  proglist() {
      IFS=: set -- $1
      find -L $@ -maxdepth 1 -perm /111 | sed ‘1d; s,.*/,,’ | sort | uniq
      unset IFS
  }
\end{code}

\subsection{Key Bindings}
\begin{code}
  «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{code}

\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{keybindings}.
               \index{filesystem!/!keys|primary}
  \item[event] The global event feed. See section \ref{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}

        When a new column, ‹n›, is created on a view whose
        name matches ‹regex›, the ‹n›th given
        ‹width› percentage of the screen is given to it. If
        there is no ‹n›th width, $1/\mbox{‹ncol›th}$ of the
        screen is given to it.

  \item[tagrules]
    \index{filesystem!/!tagrules}
        The |/tagrules| file contains a list of
        rules similar to the colrules. These rules specify
        the tags a client is to be given when it is created.
        Rules are specified:

        \begin{quote}\texttt{
          /‹regex›/ -> ‹tag›{\color{gray}[}+‹tag›{\color{gray}]*}}
        \end{quote}

        When a client's ‹name›:‹class›:‹title› matches
        ‹regex›, it is given the tagstring ‹tag›. There are
        two special tags. |!|, which is deprecated, and identical
        to |sel|, represents the current tag. |~|
        represents the floating layer.
\end{description}

\index{!filesystem!/|)}

\subsection{Configuration}

We'll need to let \wmii\ know about our previously defined theme
information:

\begin{code}
  «Configuration» ::=
  «Theme Definitions»

  xsetroot -solid $background
  wmiir write /ctl <<!
  border 2
  focuscolors $focuscolors
  normcolors $normcolors
  font $font
  grabmod Mod4
  !
\end{code}

\subsection{Key Bindings}

And we need a few more key bindings to select our views:

\begin{code}
  «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{code}

\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=: set -- $1
      find -L $@ -maxdepth 1 -perm /111 | sed ‘1d; s,.*/,,’ | 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:xwrite /client/$1/ctl kill” \
          “Kill:xwrite /client/$1/ctl slay” \
          “Fullscreen:/client/$1/ctl Fullscreen on”

      # «Tag Menu Events»
      LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
        [ $1 = 3 ] && clickmenu \
          “Delete:delete_view $2
      esac
  done
\end{code}

\backmatter

\printindex

\end{document}