summaryrefslogtreecommitdiff
path: root/doc/herbstluftwm.txt
blob: 9724612292e8ec1336fddec772a68a8ed1ae28dc (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
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
herbstluftwm(1)
===============
:doctype: manpage
:man version: {herbstluftwmversion}


NAME
----
herbstluftwm - a manual tiling window manager for X


SYNOPSIS
--------
*herbstluftwm* ['OPTION' ...]


DESCRIPTION
-----------
Starts the *herbstluftwm* window manager on 'DISPLAY'. It also listens for
calls from link:herbstclient.html[*herbstclient*(1)] and executes them. The list
of available <<COMMANDS,*COMMANDS*>> is listed below.

'OPTION' can be:

    *-c*, *--autostart* 'PATH'::
        use 'PATH' as autostart file instead of the one in '$XDG_CONFIG_HOME'
    *-v*, *--version*::
        print version and exit
    *-l*, *--locked*::
        Initially set the monitors_locked setting to 1
    *--verbose*::
        print verbose information to stderr. This can be switched at run-time by
        the 'verbose' setting.

This manual documents the scripting and configuration interface. For a more
verbose introduction see
link:tutorial.html[*herbstluftwm-tutorial*(7)].

TILING ALGORITHM
----------------
The basic tiling concept is that the layout is represented by a binary tree. On
startup you see one big frame across the entire screen. A frame fulfills
exactly one of the following conditions:

[[LIST_LAYOUT_ALGORITHMS]]
    . Frame contains windows: +
        It shows some clients and arranges them. The current layout algorithms
        are:

        * 0: 'vertical' - clients are placed below each other
        * 1: 'horizontal' - clients are placed next to each other
        * 2: 'max' - all clients are maximized in this frame
        * 3: 'grid' - clients are arranged in an almost quadratic grid

    . Frame is split into subframes: +
        It is split into exactly two *subframes* in a configurable 'fraction'
        either in a vertical or horizontal way. So it produces two *frames*
        which fulfill the same conditions (new frames always are about to
        contain *windows*). If you split a frame that already contains windows,
        the windows are inherited by the first new child frame.

If a new window appears, it is put in the currently focused frame. Only the
leaves of the frame tree can be focused.

A frame can be removed, it is then merged with its neighbour frame. Due to the
layout structure of a binary tree, each frame (i.e. node in binary tree) has
exactly one neighbour.

The analogy to a binary tree is explained the best way with a small example:
On startup you have a simple binary tree, with one frame that can contain
clients:

    C

When splitting it (e.g. with the command 'split vertical 0.5') you will get this:

    V
   / \
  C   C

You also can split the left frame horizontally and you will get:

     V
    / \
   H   C
  / \
 C   C

If you change the focus to the client on the right and remove this frame, it
will be merged with the left subtree and you will get:

   H
  / \
 C   C

The 'layout' command prints the current layout of all tags as a tree.

[[FRAME_INDEX]]
FRAME INDEX
-----------
The exact position of a frame in the layout tree may be described by its
*index* which is just a string of characters. The lookup algorithm starts at
the root frame and selects one of its two subtrees according to the each
character in the index.

The characters are interpreted as follows:

    * +0+: select the first subtree
    * +1+: select the second subtree
    * +.+: select the subtree having the focus
    * +/+: select the subtree not having the focus

Thus an empty string refers to the root frame, and "00" refers to the first
subtree of the first subtree of the root frame.

As a special case, the string "@" always refers to the currently focused
frame.

TAGS
----
Tags are very similar to workspaces, virtual desktops or window groups. Each
tag has one layout. There is a list of tags. You can add or remove tags
dynamically.

[[MONITORS]]
MONITORS
--------
Monitors in *herbstluftwm* are totally independent of the actual physical
screens. This means you can for example split your screen in two virtual
monitors to view two tags at once on a big screen.

Each monitor displays exactly one tag on a specified rectangle on the screen.

Each monitor may have a name, which can be set via *add_monitor* and
*rename_monitor*. It can be unset with the *rename_monitor* command. A monitor
name is an arbitrary non-empty string which must not start with +++, +-+ or any
digit.

A monitor can be referenced in different ways:

    * by its absolute index as listed in the *list_monitors* command.
    * by its relative index: a +++ or +-+ followed by a delta, e.g.: +3
    * by its relative position to the focused monitor. +-l+ denotes the monitor
      left of the focused monitor, +-r+ right of, +-u+ above of, and +-d+ below
      of, respectively.
    * by "" (an empty string) which represents the current monitor.
    * by its name.


[[COMMANDS]]
COMMANDS
--------
// TODO examples in fixed font in html output
*herbstluftwm* is controlled by internal commands, which can be executed via
link:herbstclient.html[*herbstclient*(1)] or via keybindings.

quit::
    Quits herbstluftwm.

reload::
    Executes the autostart file.

version::
    Prints the version of the running herbstluftwm instance.

echo ['ARGS' ...]::
    Prints all given 'ARGS' separated by a single space and a newline
    afterwards.

true::
    Ignores all arguments and always returns success, i.e. 0.

false::
    Ignores all arguments and always returns failure, i.e. 1.

list_commands::
    Lists all available commands.

[[list_monitors]]list_monitors::
    List currently configured monitors with their index, area (as rectangle),
    name (if named) and currently viewed tag.

list_rules::
    Lists all active rules. Each line consists of all the parameters the rule
    was called with, plus its label, separated by tabs.

list_keybinds::
    Lists all bound keys with their associated command. Each line consists of
    one key combination and the command with its parameters separated by tabs.

WARNING: Tabs within command parameters are not escaped!

lock::
    Increases the 'monitors_locked' setting. Use this if you want to do multiple
    window actions at once (i.e. without repainting between the single steps).
    See also: *unlock*

unlock::
    Decreases the 'monitors_locked' setting. If 'monitors_locked' is changed to
    0, then all monitors are repainted again. See also: *lock*

keybind 'KEY' 'COMMAND' ['ARGS ...']::
    Adds a key binding. When 'KEY' is pressed, the internal 'COMMAND' (with its
    'ARGS') is executed. A key binding is a (possibly empty) list of modifiers
    (Mod1, Mod2, Mod3, Mod4, Mod5, Alt, Super, Control/Ctrl, Shift) and one key
    (see keysymdef.h for a list of keys). Modifiers and the key are concatenated
    with '-' or '+' as separator. If there is already a binding for this 'KEY',
    it will be overwritten. Examples:

        * keybind Mod4+Ctrl+q quit
        * keybind Mod1-i toggle always_show_frame
        * keybind Mod1-Shift-space cycle_layout -1

keyunbind 'KEY'|*-F*|*--all*::
    Removes the key binding for 'KEY'. The syntax for 'KEY' is defined in
    *keybind*.  If *-F* or *--all* is given, then all key bindings will be
    removed.

mousebind 'BUTTON' 'ACTION' ['COMMAND' ...]::
    Adds a mouse binding for the floating mode. When 'BUTTON' is pressed, the
    specified 'ACTION' will be performed. 'BUTTON' has a similar syntax to the
    'KEY' argument of keybind: It consists of a list of modifiers (separated by
    '-' or '+', valid modifiers are listed in the description of 'keybind') and
    exactly one button name:

        * +B1+ or +Button1+
        * +B2+ or +Button2+
        * +B3+ or +Button3+
        * +B4+ or +Button4+
        * +B5+ or +Button5+
 ::
    'ACTION' must be one of the following actions:

        * +move+: Moves the window by dragging the cursor.
        * +resize+: Resizes the window by dragging a corner.
        * +zoom+: Resizes the window into all four directions while keeping the
          center of the window constant.
        * +call+: Only calls the specified 'COMMAND' while +client.dragged+
          links to the client on which the 'BUTTON' has been performed.
 ::
    While an 'ACTION' is performed, +client.dragged+ is the client which is
    dragged. E.g.:
        * +mousebind Mod1-Button3 zoom+
        * +mousebind Mod1-B4 call substitute WID clients.dragged.winid spawn
          transset-df --inc -i WID 0.05+
        * +mousebind Mod1-B5 call substitute WID clients.dragged.winid spawn
          transset-df --dec -i WID -m 0.2 0.05+

mouseunbind::
    Removes all mouse bindings.

spawn 'EXECUTABLE' ['ARGS ...']::
    Spawns an 'EXECUTABLE' with its 'ARGS'. For details see 'man 3 execvp'.
    Example:

        * spawn xterm -e man 3 execvp

wmexec ['WINDOWMANAGER' ['ARGS ...']]::
    Executes the 'WINDOWMANAGER' with its 'ARGS'. This is useful to switch the
    window manager in the running session without restarting the session. If no
    or an invalid 'WINDOWMANAGER' is given, then herbstluftwm is restarted. For
    details see 'man 3 execvp'. Example:

        * wmexec openbox

chain 'SEPARATOR' ['COMMANDS' ...]::
    chain expects a 'SEPARATOR' and a list of 'COMMANDS' with arguments. The
    commands have to be separated by the specified 'SEPARATOR'. The 'SEPARATOR'
    can by any word and only is recognized as the separator between commands if
    it exactly matches 'SEPARATOR'. "chain" outputs the appended outputs of all
    commands and returns the exit code of the last executed command. Examples
    are:

      * Create a tag called "foo" and directly use it: +
        chain , add foo , use foo
      * Rotate the layout clockwise: +
        chain .-. lock .-. rotate .-. rotate .-. rotate .-. unlock

 ::
    Counterexamples are:

      * This will only create a tag called "foo,": +
        chain , add foo, use foo
      * Separator "." defined, but "," is used: +
        chain . add foo , use foo

and 'SEPARATOR' ['COMMANDS' ...]::
    "and" behaves like the chain command but only executes the specified
    'COMMANDS' while the commands return the exit code 0.

or 'SEPARATOR' ['COMMANDS' ...]::
    "or" behaves like the chain command but only executes the specified
    'COMMANDS' until one command returns the exit code 0.

! 'COMMAND'::
    "!" executes the provided command, but inverts its return value. If the
    provided command returns a nonzero, "!" returns a 0, if the command returns
    a zero, "!" returns a 1.

try 'COMMAND'::
    "try" executes the provided command, prints its output, but always returns
    success, i.e. 0.

silent 'COMMAND'::
    "silent" executes the provided command, but discards its output and only
    returns its exit code.

focus_nth 'INDEX'::
    Focuses the nth window in a frame. The first window has 'INDEX' 0. If
    'INDEX' is negative or greater than the last window index, then the last
    window is focused.

cycle ['DELTA']::
    Cycles the selection within the current frame by 'DELTA'. If 'DELTA' is
    omitted, 'DELTA' = 1 will be used. 'DELTA' can be negative; 'DELTA' = -1
    means: cycle in the opposite direction by 1.

cycle_all [*--skip-invisible*] ['DIRECTION']::
    Cycles through all windows and frames on the current tag. 'DIRECTION' = 1
    means forward, 'DIRECTION' = -1 means backward, 'DIRECTION' = 0 has no
    effect. 'DIRECTION' defaults to 1. If there are multiple windows within on
    frame, then it acts similar to the 'cycle' command. (The 'cycle_all' command
    focuses the next/previous leaf in the 'layout' tree.). If
    *--skip-invisible* is given, then this only cycles through all visible
    windows and skips invisible windows in the max layout. The focused window
    is raised.

cycle_frame ['DIRECTION']::
    Cycles through all frames on the current tag. 'DIRECTION' = 1 means forward,
    'DIRECTION' = -1 means backward, 'DIRECTION' = 0 has no effect. 'DIRECTION'
    defaults to 1.

cycle_layout ['DELTA' ['LAYOUTS' ...]]::
    Cycles the layout algorithm in the current frame by 'DELTA'. 'DELTA'
    defaults to 1. You can find a <<LIST_LAYOUT_ALGORITHMS,list of layout
    algorithms>> above. If a list of 'LAYOUTS' is given, cycle_layout will cycle
    through those instead of the default layout algorithm list. This is done by
    finding the first occurrence of the current layout in 'LAYOUTS' and picking
    the next layout according to 'DELTA'. If the current layout doesn't occur in
    'LAYOUTS', the first entry is picked. Example:

      * cycle_layout -1
      * cycle_layout 1 vertical grid

set_layout 'LAYOUT'::
    Sets the layout algorithm in the current frame to 'LAYOUT'.  For the list of
    layouts, check the <<LIST_LAYOUT_ALGORITHMS,list of layout algorithms
    above>>.

close 'WINID'::
    Closes the specified window gracefully or the focused window if none is
    given explicitly. See the <<WINDOW_IDS, section on WINDOW IDS>> how to
    reference a certain window.

close_or_remove::
    Closes the focused window or removes the current frame if no window is
    focused.

close_and_remove::
    Closes the focused window and removes the current frame if no other window
    is present in that frame.

split 'ALIGN' ['FRACTION']::
    Splits the focused frame into two subframes with a specified 'FRACTION'
    between 0 and 1 which defaults to 0.5. 'ALIGN' is one of
    +
        * 'top'
        * 'bottom' (= 'vertical')
        * 'left',
        * 'right' (= 'horizontal')
        * 'explode'
        * 'auto' (split along longest side)
    +
    It specifies which of the two halves will be empty
    after the split. The other half will be occupied by the currently focused
    frame. After splitting, the originally focuse frame will stay focused.
    One special 'ALIGN' mode is 'explode', which splits the frame in such a way
    that the window sizes and positions are kept as much as possible. If no
    'FRACTION' is given to 'explode' mode an optimal fraction is picked
    automatically. Example:

        * split explode
        * split bottom 0.5
        * split horiz 0.3
        * split vertical 0.5
        * split h

focus ['-i'|'-e'] 'DIRECTION'::
    Moves the focus from current frame to the next frame or client in
    'DIRECTION' which is in:
    +
        * l[eft]
        * r[ight]
        * u[p]
        * d[own]

// small hack to fix indentation of "If ..."
 ::
    If '-i' (internal) is given or default_direction_external_only is unset,
    then the next client in 'DIRECTION' can also be within the same frame. If
    there is no client within this frame or '-e' (external) is given, then the
    next frame in specified 'DIRECTION' will be focused. +
    +
    The direction between frames is defined as follows: The focus is in a leaf
    of the binary tree.  Each inner node in the tree remembers the last focus
    direction (child 0 or child 1). The algorithm uses the shortest possible way
    from the leaf (the currently focused frame) to the root until it is possible
    to change focus in the specified 'DIRECTION'. From there the focus goes back
    to the leaf. +
    +
    Example: The focus is at frame A. After executing 'focus right' focus will
    be at frame C.
+
----
 Tree:  V,0     Screen: ┌─────┐┌─────┐ (before)
        ╱ ╲             │  B  ││  C  │
       ╱   ╲            └─────┘└─────┘
     H,1   H,0          ┌─────┐┌─────┐
     ╱ ╲   ╱ ╲          │  A* ││  D  │
    A*  B C   D         └─────┘└─────┘

 Tree:  V,0     Screen: ┌─────┐┌─────┐ (after focus right)
        ╱ ╲             │  B  ││  C* │
       ╱   ╲            └─────┘└─────┘
     H,1   H,0          ┌─────┐┌─────┐
     ╱ ╲   ╱ ╲          │  A  ││  D  │
    A   B C*  D         └─────┘└─────┘
----
 ::
    If the currently focused client is floated, then the next floating window in
    the specified direction is focused and raised.
 ::
    If 'focus_crosses_monitor_boundaries' is set and no client or frame is found
    in the specified 'DIRECTION', then the next monitor in that 'DIRECTION' is
    focused.


focus_edge ['-i'|'-e'] 'DIRECTION'::
    Focuses the window on the edge of the tag in the specified 'DIRECTION'. The
    'DIRECTIONS' and '-e' behave as specified at the 'focus' command. +
    +
    If '-i' (internal) is given or default_direction_external_only is unset,
    then the window on the edge of the tag will be focused. Else, only the frame
    on the edge of the tag will be focused, and the window that was last focused
    in that frame will be focused.
+

raise 'WINID'::
    Raises the specified window. See the <<WINDOW_IDS, section on WINDOW IDS>>
    on how to reference a certain window. Its result is only visible in floating
    mode.

TIP: The 'WINID' also can specify an unmanaged window, although the completion
for the raise command does not list the IDs of unmanaged windows.


jumpto 'WINID'::
    Puts the focus to the specified window. See the <<WINDOW_IDS, section on
    WINDOW IDS>> on how to reference a certain window.

bring 'WINID'::
    Moves the specified window to the current frame and focuses it. See the
    <<WINDOW_IDS, section on WINDOW IDS>> on how to reference a certain window.


resize 'DIRECTION' 'FRACTIONDELTA'::
    Changes the next fraction in specified 'DIRECTION' by 'FRACTIONDELTA'.
    'DIRECTION' behaves as specified at the 'focus' command. You should not omit
    the sign '-' or '+', because in future versions, the behaviour may change if
    the sign is omitted. Example:

        * resize right +0.05
        * resize down -0.1

shift_edge ['-i'|'-e'] 'DIRECTION'::
    Shifts the focused window to the the edge of a tag in the specified
    'DIRECTION'. The 'DIRECTIONS' behave as specified at the 'focus' command and
    '-i' and '-e' behave as specified at the 'focus_edge' command.

shift ['-i'|'-e'] 'DIRECTION'::
    Shifts the focused window to the next frame in the specified 'DIRECTION'.
    The 'DIRECTIONS' and '-i'|'-e' behave as specified at the 'focus' command.
    If the focused client is floated instead of being tiled, then client is
    shifted to the next window or screen edge.

shift_to_monitor 'MONITOR'::
    Moves the focused window to the tag on the specified 'MONITOR'.
    See the <<MONITORS,MONITORS section>>, how to address a monitor.

remove::
    Removes focused frame and merges its windows to its neighbour frame.

rotate::
    Rotates the layout on the focused tag counterclockwise by 90 degrees. This
    only manipulates the alignment of frames, not the content of them.

set 'NAME' 'VALUE'::
    Sets the specified setting 'NAME' to 'VALUE'. All <<SETTINGS,*SETTINGS*>>
    are listed in the <<SETTINGS, section below>>.

get 'NAME'::
    Prints the value of setting 'NAME'. All <<SETTINGS,*SETTINGS*>>
    are listed in the <<SETTINGS, section below>>.

toggle 'NAME'::
    Toggles the setting 'NAME' if it's an integer setting: If its value is
    unequal to 0, it becomes 0; else its previous value (which was unequal to 0)
    is restored.

cycle_value 'NAME' 'VALUES' ...::
    Cycles value of the setting 'NAME' through 'VALUES': I.e. it searches the
    first occurrence of the current value in 'VALUES' and changes the value to
    the next in the list or to the first one if the end is reached or current
    value wasn't found. Example:

        * cycle_value frame_gap 0 5 10 15
        * cycle_value frame_bg_normal_color red green blue

cycle_monitor ['DELTA']::
    Cycles monitor focused by 'DELTA'. 'DELTA' defaults to 1.

focus_monitor 'MONITOR'::
    Puts focus to the specified monitor. See the <<MONITORS,MONITORS section>>,
    how to address a monitor.

add 'TAG'::
    Creates a new empty tag named 'TAG'.

use 'TAG'::
    Switches the focused monitor to specified 'TAG'.

use_index 'INDEX' [*--skip-visible*]::
    Switches the focused monitor to the 'TAG' with the specified 'INDEX'. If
    'INDEX' starts with +++ or +-+, then 'INDEX' is treated relative to the
    current 'TAG'. If *--skip-visible* is passed and 'INDEX' is relative, then
    tags that are already visible on a monitor are skipped. E.g. this cycles
    backwards through the tags:

        * use_index -1 --skip-visible

use_previous::
    Switches the focused monitor to the previously viewed tag.

merge_tag 'TAG' ['TARGET']::
    Removes tag named 'TAG' and moves all its windows to tag 'TARGET'. If
    'TARGET' is omitted, the focused tag will be used.

rename 'OLDTAG' 'NEWTAG'::
    Renames tag named 'OLDTAG' to 'NEWTAG'.

move 'TAG'::
    Moves the focused window to the tag named 'TAG'.

move_index 'INDEX' [*--skip-visible*]::
    Moves the focused window to the tag specified by 'INDEX'. Analogical to the
    argument for *use_index*: If 'INDEX' starts with +++ or +-+, then it is
    treated relative. If *--skip-visible* is passed with a relative index, then
    already visible tags are skipped.

lock_tag ['MONITOR']::
    Lock the tag switching on the specified monitor. If no
    argument is given, the currently focused monitor is used. When the
    tag switching is disabled for a monitor, the commands *use* and
    *use_index* have no effect when executed there. When
    'swap_monitors_to_get_tag' is enabled, switching to a tag which
    is located on a locked monitor, switches to that monitor instead of
    stealing it from there. The lock state of a monitor is indicated
    by "[LOCKED]" in the *list_monitors* output.

unlock_tag ['MONITOR']::
    Re-enables the tag switching on the specified monitor. If no argument is
    given, the currently focused  monitor is used. This is the reverse operation
    to *lock_tag* and has no further side effects but removing this lock.

disjoin_rects 'RECTS' ...::
    Takes a list of rectangles and splits them into smaller pieces until all
    rectangles are disjoint, the result rectangles are printed line by line.
    This command does not modify the current list of monitors! So this can be
    useful in combination with the set_monitors command.

        * E.g. +disjoin_rects 600x400+0+0 600x400+300+250+ prints this:
+
----
300x150+300+250
600x250+0+0
300x150+0+250
300x150+600+250
600x250+300+400
----
+
        * In the above example two monitors are split into 5 monitors, which
          graphically means:
+
----
┌──────┐                  ┌──────┐
│      │                  └──────┘
│  ┌───┼───┐              ┌─┐┌───┐┌──┐
│  │   │   │   disjoin    │ ││   ││  │
└──┼───┘   │  ─────────>  └─┘└───┘└──┘
   │       │                 ┌───────┐
   └───────┘                 └───────┘
----

set_monitors 'RECTS' ...::
    Sets the list of monitors *exactly* to the list of given rectangles:

        * The i'th existing monitor is moved to the i'th given 'RECT'
        * New monitors are created if there are more 'RECTS' then monitors
        * Existing monitors are deleted if there are more monitors then 'RECTS'

detect_monitors '-l'|'--list'|'--no-disjoin'::
    Sets the list of monitors to the available Xinerama monitors. If the
    Xinerama extension is missing, it will fall back to one monitor across the
    entire screen. If the detected monitors overlap, the will be split into more
    monitors that are disjoint but cover the same area using +disjoin_rects+.
    +
    If '-l' or '--list' is passed, the list of rectangles of detected pyhsical
    monitors is printed. So +hc detect_monitors+ is equivalent to the bash
    command +hc set_monitors $(hc disjoin_rects $(hc detect_monitors -l))+.

add_monitor 'RECT' ['TAG' ['NAME']]::
    Adds a monitor on the specified rectangle 'RECT' and displays 'TAG' on it.
    'TAG' currently must not be displayed on any other monitor. 'RECT' is a
    string of the form 'WxH±X±Y'. If no or an empty 'TAG' is given, then any
    free tag will be chosen. If a 'NAME' is given, you can reference to this
    monitor by its name instead of using an index. Example:

        * add_monitor 1024x768-20+0 mynewtag main


remove_monitor 'MONITOR'::
    Removes the specified monitor.

move_monitor 'MONITOR' 'RECT' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]::
    Moves the specified monitor to rectangle 'RECT'. 'RECT' is defined as in
    'add_monitor'. If no or an empty pad is given, it is not changed.

raise_monitor ['MONITOR']::
    Raises the specified monitor or the current one if 'MONITOR' is
    omitted.

rename_monitor 'MONITOR' 'NAME'::
    (Re)names an already existing monitor. If 'NAME' is empty, it removes the
    monitor's name.

stack::
    Prints the stack of monitors with the visible tags and their layers as a
    tree. The order of the printed stack is top to bottom. The style is
    configured by the 'tree_style' setting.

monitor_rect [[-p] 'MONITOR']::
    Prints the rectangle of the specified monitor in the format: *X Y W H* +
    If no 'MONITOR' or 'cur' is given, then the current monitor is used. If '-p'
    is supplied, then the remaining rect without the pad around this monitor
    is printed.

pad 'MONITOR' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]::
    Sets the pad of specified monitor to the specified padding. If no or an
    empty padding is given, it is not changed.

list_padding ['MONITOR']::
    Lists the padding of the specified monitor, or the currently focused monitor
    if no monitor is given.

layout ['TAG' ['INDEX']]::
    Prints the layout of frame with 'INDEX' on 'TAG', in a nice tree style.
    Its style is defined by the 'tree_style' setting. If no 'TAG' is given,
    the current tag is used. If no 'INDEX' is given, the root frame is used. To
    specify 'INDEX' without specifying 'TAG' (i.e. use current tag), pass an
    empty string as 'TAG'.
    +
An example output is:
+
----
╾─┐ horizontal 50% selection=1
  ├─╼ vertical: 0xe00009
  └─┐ vertical 50% selection=0
    ├─╼ vertical: 0xa00009 [FOCUS]
    └─╼ vertical: 0x1000009
----

dump ['TAG' ['INDEX']]::
    Prints the same information as the 'layout' command but in a machine
    readable format. Its output can be read back with the 'load' command.
    +
An example output (formatted afterwards) is:
+
----
(split horizontal:0.500000:1
    (clients vertical:0 0xe00009)
    (split vertical:0.500000:1
        (clients vertical:0 0xa00009)
        (clients vertical:0 0x1000009)))
----

load ['TAG'] 'LAYOUT'::
    Loads a given 'LAYOUT' description to specified 'TAG' or current tag if no
    'TAG' is given.

CAUTION: 'LAYOUT' is exactly one parameter. If you are calling it manually
from your shell or from a script, quote it properly!

complete 'POSITION' ['COMMAND' 'ARGS ...']::
    Prints the result of tab completion for the partial 'COMMAND' with optional
    'ARGS'. You usually do not need this, because there is already tab
    completion for bash. Example:

        * complete 0 m +
          prints all commands beginning with m
        * complete 1 toggle fra +
          prints all settings beginning with fra that can be toggled

complete_shell 'POSITION' ['COMMAND' 'ARGS ...']::
    Behaves like *complete* with the following extras, useful for completion on
    posix shells:

        * Escape sequences are removed in 'COMMAND' and 'ARGS'.
        * A space is appended to each full completion result.
        * Special characters will be escaped in the output.

emit_hook 'ARGS ...'::
    Emits a custom hook to all idling herbstclients.

tag_status ['MONITOR']::
    Print a tab separated list of all tags for the specified 'MONITOR' index. If
    no 'MONITOR' index is given, the focused monitor is used. Each tag name is
    prefixed with one char, which indicates its state:
        * *.* the tag is empty
        * *:* the tag is not empty
        * *+* the tag is viewed on the specified 'MONITOR', but this monitor is
          not focused.
        * *#* the tag is viewed on the specified 'MONITOR' and it is focused.
        * *-* the tag is viewed on a different 'MONITOR', but this monitor is
          not focused.
        * *%* the tag is viewed on a different 'MONITOR' and it is focused.
        * *!* the tag contains an urgent window

WARNING: If you use a tab in one of the tag names, then tag_status is probably
quite useless for you.

floating [['TAG'] *on*|*off*|*toggle*|*status*]::
    Changes the current tag to floating/tiling mode on specified 'TAG' or prints
    it current status. If no 'TAG' is given, the current tag is used. If no
    argument is given, floating mode is toggled. If *status* is given, then *on*
    or *off* is printed, depending of the floating state of 'TAG'.

rule [\[--]'FLAG'|\[--]'LABEL'|\[--]'CONDITION'|\[--]'CONSEQUENCE' ...]::
    Defines a rule which will be applied to all new clients. Its behaviour is
    described in the <<RULES,*RULES section*>>.

unrule 'LABEL'|*--all*|*-F*::
    Removes all rules named 'LABEL'. If --all or -F is passed, then all rules
    are removed.

fullscreen [*on*|*off*|*toggle*]::
    Sets or toggles the fullscreen state of the focused client. If no argument
    is given, fullscreen mode is toggled.

pseudotile [*on*|*off*|*toggle*]::
    Sets or toggles the pseudotile state of the focused client. If a client is
    pseudotiled, then in tiling mode the client is only moved but not resized -
    the client size will stay the floating size. The only reason to resize the
    client is to ensure that it fits into its tile. If no argument is given,
    pseudotile mode is toggled.

object_tree ['PATH']::
    Prints the tree of objects. If the object path 'PATH' is given, only the
    subtree starting at 'PATH' is printed. See the <<OBJECTS,*OBJECTS section*>>
    for more details.

attr ['PATH' ['NEWVALUE']::
    Prints the children and attributes of the given object addressed by 'PATH'.
    If 'PATH' is an attribute, then print the attribute value. If 'NEWVALUE' is
    given, assign 'NEWVALUE' to the attribute given by 'PATH'. See the
    <<OBJECTS,*OBJECTS section*>> for more details.

get_attr 'ATTRIBUTE'::
    Print the value of the specified 'ATTRIBUTE' as described in the
    <<OBJECTS,*OBJECTS section*>>.

set_attr 'ATTRIBUTE' 'NEWVALUE'::
    Assign 'NEWVALUE' to the specified 'ATTRIBUTE' as described in the
    <<OBJECTS,*OBJECTS section*>>.

new_attr [*bool*|*color*|*int*|*string*|*uint*] 'PATH'::
    Creates a new attribute with the name and in the object specified by 'PATH'.
    Its type is specified by the first argument. The attribute name has to begin
    with +my_+.

remove_attr 'PATH'::
    Removes the user defined attribute 'PATH'.

substitute 'IDENTIFIER' 'ATTRIBUTE' 'COMMAND' ['ARGS' ...]::
    Replaces all exact occurrences of 'IDENTIFIER' in 'COMMAND' and its 'ARGS'
    by the value of the 'ATTRIBUTE'. Note that the 'COMMAND' also is replaced by
    the attribute value if it equals 'IDENTIFIER'. The replaced command with its
    arguments then is executed. Example:

        * +substitute MYTITLE clients.focus.title echo MYTITLE+ +
          +
          Prints the title of the currently focused window.

sprintf 'IDENTIFIER' 'FORMAT' ['ATTRIBUTES' ...] 'COMMAND' ['ARGS' ...]::
    Replaces all exact occurrences of 'IDENTIFIER' in 'COMMAND' and its 'ARGS'
    by the string specified by 'FORMAT'. Each +%s+ in 'FORMAT' stands for the
    value of the next attribute in 'ATTRIBUTES', similar to the *printf*(1)
    command. The replaced command with its arguments then is executed.
    Examples:

        * +sprintf STR title=%s clients.focus.title echo STR+ +
          +
          Prints the title of the currently focused window prepended by
          +title=+.
        * +sprintf X tag=%s tags.focus.name rule once X+ +
          +
          Moves the next client that appears to the tag that is currently
          focused.
        * +sprintf X %s/%s tags.focus.index tags.count echo X+ +
          +
          Tells which tag is focused and how many tags there are
        * +sprintf l somelongstring echo l l l+ +
          +
          Prints +somelongstring+ three times, separated by spaces.

mktemp [*bool*|*int*|*string*|*uint*] 'IDENTIFIER' 'COMMAND' ['ARGS' ...]::
    Creates a temporary attribute with the given type and replaces all
    occurrences of 'IDENTIFIER' in 'COMMAND' and 'ARGS' by by the path of the
    temporary attribute. The replaced command with its arguments is executed
    then. The exit status of 'COMMAND' is returned.

compare 'ATTRIBUTE' 'OPERATOR' 'VALUE'::
    Compares the value of 'ATTRIBUTE' with 'VALUE' using the comparison method
    'OPERATOR'. If the comparison succeeds, it returns 0, else 1. The operators
    are:
        - *=*: __ATTRIBUTE__'s value equals 'VALUE'
        - *!=*: __ATTRIBUTE__'s value does not equal 'VALUE'
        - *le*: __ATTRIBUTE__'s value \<= 'VALUE'
        - *lt*: __ATTRIBUTE__'s value <  'VALUE'
        - *ge*: __ATTRIBUTE__'s value >= 'VALUE'
        - *gt*: __ATTRIBUTE__'s value >  'VALUE'

 ::
    The 'OPERATORs' *le*,*lt*,*ge*,*gt* can only be used if 'ATTRIBUTE' is of
    the type integer or unsigned integer. Note that the first parameter must
    always be an attribute and the second a constant value. If you want to
    compare two attributes, use the substitute command:
+
----
substitute FC tags.focus.frame_count \
    compare tags.focus.client_count gt FC
----
+
It returns success if there are more clients on the focused tag than frames.

getenv 'NAME'::
    Gets the value of the environment variable 'NAME'.

setenv 'NAME' 'VALUE'::
    Set the value of the environment variable 'NAME' to 'VALUE'.

unsetenv 'NAME'::
    Unsets the environment variable 'NAME'.

[[SETTINGS]]
SETTINGS
--------
Settings configure the behaviour of herbstluftwm and can be controlled via the
'set', 'get' and 'toggle' commands. There are two types of settings: Strings and
integer values. An integer value is set, if its value is 1 or another value
unequal to 0. An integer value is unset, if its value is 0.

frame_gap (Integer)::
    The gap between frames in the tiling mode.

frame_padding (Integer)::
    The padding within a frame in the tiling mode, i.e. the space between the
    border of a frame and the windows within it.

window_gap (Integer)::
    The gap between windows within one frame in the tiling mode.

snap_distance (Integer)::
    If a client is dragged in floating mode, then it snaps to neighbour clients
    if the distance between them is smaller then snap_distance.

snap_gap (Integer)::
    Specifies the remaining gap if a dragged client snaps to an edge in floating
    mode. If snap_gap is set to 0, no gap will remain.

mouse_recenter_gap (Integer)::
    Specifies the gap around a monitor. If the monitor is selected and
    the mouse position would be restored into this gap, it is set to
    the center of the monitor. This is useful, when the monitor was
    left via mouse movement, but is reselected by keyboard. If the gap
    is 0 (default), the mouse is never recentered.

frame_border_active_color (String/Color)::
    The border color of a focused frame.

frame_border_normal_color (String/Color)::
    The border color of an unfocused frame.

frame_border_inner_color (String/Color)::
    The color of the inner border of a frame.

frame_bg_active_color (String/Color)::
    The fill color of a focused frame.

frame_bg_normal_color (String/Color)::
    The fill color of an unfocused frame (It is only visible if
    always_show_frame is set).

frame_bg_transparent (Integer)::
    If set, the background of frames are transparent. That means a rectangle is
    cut out frome the inner such that only the frame border and a stripe of
    width 'frame_transparent_width' can be seen. Use 'frame_active_opacity' and
    'frame_normal_opacity' for real transparency.

frame_transparent_width (Integer)::
    Specifies the width of the remaining frame colored with
    'frame_bg_active_color' if 'frame_bg_transparent' is set.

frame_border_width (Integer)::
    Border width of a frame.

frame_border_inner_width (Integer)::
    The width of the inner border of a frame. Must be less than
    frame_border_width, since it does not add to the frame border width but is a
    part of it.

focus_crosses_monitor_boundaries (Integer)::
    If set, the +focus+ command crosses monitor boundaries. If there is no
    client in the direction given to +focus+, then the monitor in the specified
    direction is focused.

raise_on_focus (Integer)::
    If set, a window is raised if it is focused. The value of this setting is
    only used in floating mode.

raise_on_focus_temporarily (Integer)::
    If set, a window is raised temporarily if it is focused on its tag.
    Temporarily in this case means that the window will return to its previous
    stacking position if another window is focused.

raise_on_click (Integer)::
    If set, a window is raised if it is clicked. The value of this setting is
    only noticed in floating mode.

window_border_width (Integer)::
    Border width of a window.

window_border_inner_width (Integer)::
    The width of the inner border of a window. Must be less than
    window_border_width, since it does not add to the window border width but is
    a part of it.

window_border_active_color (String/Color)::
    Border color of a focused window.

window_border_normal_color (String/Color)::
    Border color of an unfocused window.

window_border_urgent_color (String/Color)::
    Border color of an unfocused but urgent window.

window_border_inner_color (String/Color)::
    Color of the inner border of a window.

always_show_frame (Integer)::
    If set, all frames are displayed. If unset, only frames with focus or with
    windows in it are displayed.

frame_active_opacity (Integer)::
    Focused frame opacity in percent. Requires a running compositing manager to
    take actual effect.

frame_normal_opacity (Integer)::
    Unfocused frame opacity in percent. Requires a running compositing manager
    to take actual effect.

default_frame_layout (Integer)::
    Index of the frame layout, which is used if a new frame is created (by split
    or on a new tag). For a list of valid indices and their meanings, check the
    <<LIST_LAYOUT_ALGORITHMS,list of layout algorithms above>>.

default_direction_external_only (Integer)::
    This setting controls the behaviour of focus and shift if no '-e' or '-i'
    argument is given. if set, then focus and shift changes the focused frame
    even if there are other clients in this frame in the specified 'DIRECTION'.
    Else, a client within current frame is selected if it is in the specified
    'DIRECTION'.

gapless_grid (Integer)::
    This setting affects the size of the last client in a frame that is arranged
    by grid layout. If set, then the last client always fills the gap within
    this frame. If unset, then the last client has the same size as all other
    clients in this frame.

smart_frame_surroundings (Integer)::
    If set, frame borders and gaps will be removed when there's no ambiguity
    regarding the focused frame.

smart_window_surroundings (Integer)::
    If set, window borders and gaps will be removed and minimal when there's no
    ambiguity regarding the focused window. This minimal window decoration can
    be configured by the +theme.minimal+ object.

focus_follows_mouse (Integer)::
    If set and a window is focused by mouse cursor, this window is focused (this
    feature is also known as sloppy focus). If unset, you need to click to
    change the window focus by mouse. +
    +
    If another window is hidden by the focus change (e.g. when having
    pseudotiled windows in the max layout) then an extra click is required to
    change the focus.

focus_stealing_prevention (Integer)::
    If set, only pagers and taskbars are allowed to change the focus. If unset,
    all applications can request a focus change.

monitors_locked (Integer)::
    If greater than 0, then the clients on all monitors aren't moved or resized
    anymore. If it is set to 0, then the arranging of monitors is enabled again,
    and all monitors are rearranged if their content has changed in the
    meantime. You should not change this setting manually due to concurrency
    issues; use the commands *lock* and *unlock* instead.

swap_monitors_to_get_tag (Integer)::
    If set: If you want to view a tag, that already is viewed on another
    monitor, then the monitor contents will be swapped and you see the wanted
    tag on the focused monitor. If not set, the other monitor is focused if it
    shows the desired tag.

auto_detect_monitors (Integer)::
    If set, detect_monitors is automatically executed every time a monitor is
    connected, disconnected or resized.

tree_style (String)::
    It contains the chars that are used to print a nice ascii tree. It must
    contain at least 8 characters. e.g. ++X|:#+*-.++ produces a tree like:
+
----
X-.root
  #-. child 0
  | #-* child 01
  | +-* child 02
  +-. child 1
  : #-* child 10
  : +-* child 01
----
+
Useful values for 'tree_style' are: +╾│ ├└╼─┐+ or +-| |'--.+ or +╾│ ├╰╼─╮+.

wmname (String)::
    It controls the value of the +_NET_WM_NAME+ property on the root window,
    which specifies the name of the running window manager. The value of this
    setting is not updated if the actual +_NET_WM_NAME+ property on the root
    window is changed externally. Example usage:

        * cycle_value wmname herbstluftwm LG3D

pseudotile_center_threshold (Int)::
    If greater than 0, it specifies the least distance between a centered
    pseudotile window and the border of the frame or tile it is assigned to. If
    this distance is lower than 'pseudotile_center_threshold', it is aligned to
    the top left of the client's tile.

update_dragged_clients (Int)::
    If set, a client's window content is resized immediately during resizing
    it with the mouse. If unset, the client's content is resized after the mouse
    button are released.

verbose (Int)::
    If set, verbose output is logged to herbstluftwm's stderr. The default value
    is controlled by the *--verbose* command line flag.

[[RULES]]
RULES
-----

Rules are used to change default properties for certain clients when they
appear. Each rule matches against a certain subset of all clients and defines a
set of properties for them (called __CONSEQUENCE__s). A rule can be defined
with this command:

+rule+ [\[--]'FLAG'|\[--]'LABEL'|\[--]'CONDITION'|\[--]'CONSEQUENCE' ...]

Each rule consists of a list of __FLAG__s, __CONDITION__s, __CONSEQUENCE__s
and, optionally, a 'LABEL'. (each of them can be optionally prefixed with two
dashes (+--+) to provide a more *iptables*(8)-like feeling).

Each rule can be given a custom label by specifying the 'LABEL' property:

    * +[--]label+='VALUE'

If multiple labels are specified, the last one in the list will be applied. If
no label is given, then the rule will be given an integer name that represents
the index of the rule since the last 'unrule -F' command (which is triggered in
the default autostart).

TIP: Rule labels default to an incremental index. These default labels are
unique, unless you assign a different rule a custom integer 'LABEL'. Default
labels can be captured with the 'printlabel' flag.

If a new client appears, herbstluftwm tries to apply each rule to this new
client as follows: If each 'CONDITION' of this rule matches against this client,
then every 'CONSEQUENCE' is executed. (If there are no conditions given, then
this rule is executed for each client)

Each 'CONDITION' consists of a 'property' name, an operator and a 'value'. Valid
operators are:

    * +~+ matches if client's 'property' is matched by the regex 'value'.
    * +=+ matches if client's 'properly' string is equal to 'value'.

Valid 'properties' are:

+instance+::
    the first entry in client's +WM_CLASS+.

+class+::
    the second entry in client's +WM_CLASS+.

+title+::
    client's window title.

+pid+::
    the client's process id (Warning: the pid is not available for every client.
    This only matches if the client sets _NET_WM_PID to the pid itself).

+maxage+::
    matches if the age of the rule measured in seconds does not exceed 'value'.
    This condition only can be used with the +=+ operator. If maxage already is
    exceeded (and never will match again), then this rule is removed. (With this
    you can build rules that only live for a certain time.)

+windowtype+::
    matches the _NET_WM_WINDOW_TYPE property of a window.

+windowrole+::
    matches the WM_WINDOW_ROLE property of a window if it is set by the window.

Each 'CONSEQUENCE' consists of a 'NAME'='VALUE' pair. Valid 'NAMES' are:

+tag+::
    moves the client to tag 'VALUE'.

+monitor+::
    moves the client to the tag on monitor 'VALUE'. If the tag consequence was
    also specified, and switchtag is set for the client, move the client to that
    tag, then display that tag on monitor 'VALUE'. If the tag consequence was
    specified, but switchtag was not, ignore this consequence.

+focus+::
    decides whether the client gets the input focus on his tag.  The default is
    *off*. 'VALUE' can be *on*, *off* or *toggle*.

+switchtag+::
    if +focus+ is activated and the client is put to a not focused tag, then
    +switchtag+ tells whether the client's tag will be shown or not. If the tag
    is shown on any monitor but is not focused, the client's tag only is brought
    to the current monitor if *swap_monitors_to_get_tag* is activated. 'VALUE'
    can be *on*, *off* or *toggle*.

+manage+::
    decides whether the client will be managed or not. The default is *on*.
    'VALUE' can be *on*, *off* or *toggle*.

+index+::
    moves the window to a specified index in the tree. 'VALUE' is a
    <<FRAME_INDEX,*frame index*>>.

+pseudotile+::
    sets the pseudotile state of the client. 'VALUE' can be *on*, *off* or
    *toggle*.

+ewmhrequests+::
    sets whether the window state (the fullscreen state and the demands
    attention flag) can be changed by the application via ewmh itself. This does
    not affect the initial fullscreen state requested by the window. 'VALUE' can
    be *on*, *off* or *toggle*, it defaults to *on*.

+ewmhnotify+::
    sets whether hlwm should let the client know about EMWH changes (currently
    only the fullscreen state). If this is set, applications do not change to
    their fullscreen-mode while still being fullscreen. 'VALUE' can be *on*,
    *off* or *toggle*, it defaults to *on*.

+fullscreen+::
    sets the fullscreen flag of the client. 'VALUE' can be *on*, *off* or
    *toggle*.

+hook+::
    emits the custom hook +rule+ 'VALUE' 'WINID' when this rule is triggered by
    a new window with the id 'WINID'. This consequence can be used multiple
    times, which will cause a hook to be emitted for each occurrence of a hook
    consequence.

+keymask+::
    Sets the keymask for an client. A keymask is an regular expression that is
    matched against the string represenation (see list_keybinds). If it matches
    the keybinding is active when this client is focused, otherwise it is
    disabled. The default keymask is an empty string (""), which does not
    disable any keybinding.

A rule's behaviour can be configured by some special 'FLAGS':

    * +not+: negates the next 'CONDITION'.
    * +!+: same as +not+.
    * +once+: only apply this rule once (and delete it afterwards).
    * +printlabel+: prints the label of the newly created rule to stdout.
    * +prepend+: prepend the rule to the list of rules instead of appending it.
      So its consequences may be overwritten by already existing rules.

Examples:

    * +rule --class=Netscape --tag=6 --focus=off+ +
        +
        Moves all Netscape instances to tag 6, but doesn't give focus to them.

    * +rule not class~.*[Tt]erm tag=2+ +
        +
        Moves all clients to tag 2, if their class does not end with +term+ or
        +Term+.

    * +rule class=Thunderbird index=/0+
        +
        Insert all Thunderbird instances in the tree that has no focus and there
        in the first child.

    * +rule --windowtype=_NET_WM_WINDOW_TYPE_DIALOG --focus=on+
        +
        Sets focus to new dialogs which set their +_NET_WM_WINDOW_TYPE+ correctly.

[[WINDOW_IDS]]
WINDOW IDS
----------
Several commands accept a window as reference, e.g. +close+. The syntax is as
follows:

  - an empty string -- or missing argument -- references the currently focused
    window.
  - +urgent+ references some window that is urgent.
  - +0x+'HEXID' -- where 'HEXID' is some hexadecimal number -- references the
    window with hexadecimal X11 window id is 'HEXID'.
  - 'DECID' -- where 'DECID' is some decimal number -- references the window
    with the decimal X11 window id 'DECID'.

[[OBJECTS]]
OBJECTS
-------

WARNING: The object tree is not stable yet, i.e. its interface may change until
the next stable release. So check this documentation again after upgrading the
next time.

The object tree is a collection of objects with attributes similar to +/sys+
known from the Linux kernel. Many entities (like tags, monitors, clients, ...)
have objects to access their attributes directly. The tree is printed by the
+object_tree+ command and looks more or less as follows:
----
$ herbstclient object_tree
╾─┐
  ├─┐ tags
  │ ├─┐ by-name
  │ │ ├─╼ 1
  │ │ ...
  │ │ └─╼ 9
  │ └─╼ focus
  ├─┐ clients
  │ ├─╼ 0x1400022
  │ └─╼ focus
  └─┐ monitors
    ├─╼ by-name
    └─╼ focus
----
To print a subtree starting at a certain object, pass the 'PATH' of the object
to +object_tree+. The object 'PATH' is the path using the separator +.+ (dot),
e.g. +tags.by-name+:

----
$ herbstclient object_tree tags.by-name.
╾─┐ tags.by-name.
  ├─╼ 1
  ├─╼ 2
  ...
  └─╼ 9
----

To query all attributes and children of a object, pass its 'PATH' to +attr+:

----
$ herbstclient attr tags.
2 children:
  by-name.
  focus.

1 attributes:
 .---- type
 | .-- writeable
 V V
 u - count                = 9

$ herbstclient attr tags.focus.
0 children.
6 attributes:
 .---- type
 | .-- writeable
 V V
 s w name                 = "1"
 b w floating             = false
 i - frame_count          = 2
 i - client_count         = 1
 i - curframe_windex      = 0
 i - curframe_wcount      = 1
----

This already gives an intuition of the output: +attr+ first lists the names of
the child objects and then all attributes, telling for each attribute:

  - its type

    * +s+ for string
    * +i+ for integer
    * +b+ for boolean
    * +u+ for unsigned integer

  - if it is writeable by the user: +w+ if yes, +-+ else.
  - the name of the attribute
  - its current value (only quoted for strings)

To get the unquoted value of a certain attribute, address the attribute using
the same syntax as for object paths and pass it to +attr+ or +get_attr+:

----
$ herbstclient attr clients.focus.title
herbstluftwm.txt = (~/dev/c/herbstluftwm/doc) - VIM
$ herbstclient get_attr  clients.focus.title
herbstluftwm.txt = (~/dev/c/herbstluftwm/doc) - VIM
----

To change a writeable attribute value pass the new value to +attr+ or to
+set_attr+:

----
$ herbstclient attr tags.focus.floating
false
$ herbstclient attr tags.focus.floating true
$ herbstclient attr tags.focus.floating
true
$ herbstclient set_attr tags.focus.floating false
$ herbstclient attr tags.focus.floating
false
----

Just look around to get a feeling what is there. The detailed tree content is
listed as follows:

  * +tags+: subtree for tags.
+
[format="csv",cols="m,"]
|===========================
 u - count                , number of tags
|===========================
    ** 'index': the object of the tag with index 'index'.
    ** +by-name+
        *** 'TAG': an object for each tag with the name 'TAG' +
+
[format="csv",cols="m,"]
|===========================
 s w name                 , name of the tag
 b w floating             , if it is in floating mode
 i - index                , index of this tag
 i - frame_count          , number of frames
 i - client_count         , number of clients on this tag
 i - curframe_windex      , index of the focused client in the select frame
 i - curframe_wcount      , number of clients in the selected frame
|===========================

    ** +focus+: the object of the focused tag

  * +clients+
    ** 'WINID': a object for each client with its 'WINID' +
+
[format="csv",cols="m,"]
|===========================
 s - winid                , its window id
 s - title                , its window title
 s - tag                  , the tag it's currently on
 i - pid                  , the process id of it (-1 if unset)
 s - class                , the class of it (second entry in WM_CLASS)
 s - instance             , the instance of it (first entry in WM_CLASS)
 b w fullscreen           ,
 b w pseudotile           ,
 b w ewmhrequests         , if ewmh requests are permitted for this client
 b w ewmhnotify           , if the client is told about its state via ewmh
 b w urgent               , its urgent state
 b w sizehints_tiling     , if sizehints for this client should be respected in tiling mode
 b w sizehints_flaoting   , if sizehints for this client should be respected in floating mode
|===========================

    ** +focus+: the object of the focused client, if any
    ** +dragged+: the object of a client which is dragged by the mouse, if any.
      See the documentation of the +mousebind+ command for examples.

  * +monitors+
+
[format="csv",cols="m,"]
|===========================
 u - count                , number of monitors
|===========================
    ** 'INDEX': a object for each monitor with its 'INDEX' +
    ** +by-name+
      *** 'NAME': a object for each named monitor +
+
[format="csv",cols="m,"]
|===========================
 s - name                 , its name
 i - index                , its index
 s - tag                  , the tag currently viewed on it
 b - lock_tag             ,
|===========================

    ** +focus+: the object of the focused monitor

  * +settings+ has an attribute for each setting. See <<SETTINGS,*SETTINGS*>>
    for a list.
  * +theme+ has attributes to configure the window decorations. +theme+ and many
    of its child objects have the following attributes
+
[format="csv",cols="m,"]
|===========================
 i w border_width         , the base width of the border
 i w padding_top          , additional border width on the top
 i w padding_right        , on the right
 i w padding_bottom       , on the bottom
 i w padding_left         , and on the left of the border
 c w color                , the basic background color of the border
 i w inner_width          , width of the border around the clients content
 c w inner_color          , its color
 i w outer_width          , width of an additional border close to the edge
 c w outer_color          , its color
 c w background_color     , color behind window contents visible on resize
 s w reset                , Writing this resets all attributes to a default value
|===========================
+
----
inner_color/inner_width
      ╻        outer_color/outer_width
      │                  ╻
      │                  │
┌────╴│╶─────────────────┷─────┐ ⎫ border_width
│     │      color             │ ⎬     +
│  ┌──┷─────────────────────┐  │ ⎭ padding_top
│  │====================....│  │
│  │== window content ==....│  │
│  │====================..╾──────── background_color
│  │........................│  │
│  └────────────────────────┘  │ ⎱ border_width +
└──────────────────────────────┘ ⎰ padding_bottom
----
+
Setting an attribute of the +theme+ object just propagates the value to the
respective attribute of the +tiling+ and the +floating+ object.

    ** +tiling+ configures the decoration of tiled clients, setting one of its
       attributes propagates the respective attribute of the +active+, +normal+
       and +urgent+ child objects.

       *** +active+ configures the decoration of focused and tiled clients
       *** +normal+ configures the decoration of unfocused and tiled clients
       *** +urgent+ configures the decoration of urgent and tiled clients

   ** +floating+ behaves analogously to +tiling+
   ** +minimal+ behaves analogously to +tiling+ and configures those minimal
      decorations triggered by +smart_window_surroundings+.
   ** +active+ propagates the attribute values to +tiling.active+ and
      +floating.active+
   ** +normal+ propagates the attribute values to +tiling.normal+ and
      +floating.normal+
   ** +urgent+ propagates the attribute values to +tiling.urgent+ and
      +floating.urgent+

[[AUTOSTART]]
AUTOSTART FILE
--------------

There is no configuration file but an autostart file, which is executed on
startup. It is also executed on command 'reload'. If not specified by the
*--autostart* argument, autostart file is located at
'$XDG_CONFIG_HOME/herbstluftwm/autostart' or at
'~/.config/herbstluftwm/autostart'. Normally it consists of a few *herbstclient*
calls. If executing the autostart file in a user's home fails the global
autostart file (mostly placed at /etc/xdg/herbstluftwm/autostart) is executed as
a fallback.

For a quick install, copy the default autostart file to
'~/.config/herbstluftwm/'.

HOOKS
-----

On special events, herbstluftwm emits some hooks (with parameters). You can
receive or wait for them with link:herbstclient.html[*herbstclient*(1)]. Also custom hooks can be
emitted with the *emit_hook* command. The following hooks are emitted by
herbstluftwm itself:

fullscreen [on|off] 'WINID' 'STATE'::
    The fullscreen state of window 'WINID' was changed to [on|off].

tag_changed 'TAG' 'MONITOR'::
    The tag 'TAG' was selected on 'MONITOR'.

focus_changed 'WINID' 'TITLE'::
    The window 'WINID' was focused. Its window title is 'TITLE'.

window_title_changed 'WINID' 'TITLE'::
    The title of the *focused* window was changed. Its window id is 'WINID' and
    its new title is 'TITLE'.

tag_flags::
    The flags (i.e. urgent or filled state) have been changed.

tag_added 'TAG'::
    A tag named 'TAG' was added.

tag_removed 'TAG'::
    The tag named 'TAG' was removed.

urgent [on|off] 'WINID'::
    The urgent state of client with given 'WINID' has been changed to [on|off].

rule 'NAME' 'WINID'::
    A window with the id 'WINID' appeared which triggered a rule with the
    consequence hook='NAME'.

There are also other useful hooks, which never will be emitted by herbstluftwm
itself, but which can be emitted with the *emit_hook* command:

quit_panel::
    Tells a panel to quit. The default panel.sh quits on this hook. Many
    scripts are using this hook.

reload::
    Tells all daemons that the 'autostart' file is reloaded -- and tells them
    to quit. This hook *should* be emitted in the first line of every 'autostart'
    file.

[[STACKING]]
STACKING
--------
Every tag has its own stack of clients that are on this tag. Similar to the EWMH
specification each tag stack contains several layers, which are from top to
bottom:

  * the focused client (if raise_on_focus_temporarily is enabled)
  * clients in fullscreen
  * normal clients
  * frame decorations

All monitors are managed in one large stack which only consists of the stacks of
the visible tags put above each other. The stacking order of these monitors is
independent from their indices and can be modified using the *raise_monitor*
command. The current stack is illustrated by the *stack* command.

[[EWMH]]
EWMH
----
As far as possible, herbstluftwm tries to be EWMH compliant. That includes:

  - Information about tag names and client lists is provided.
  - Desktop windows from desktop environments are not managed and kept below the
    other windows.
  - Client requests like getting focused are only processed if the setting
    'focus_stealing_prevention' is disabled.

ENVIRONMENT VARIABLES
---------------------
DISPLAY::
    Specifies the 'DISPLAY' to use.


FILES
-----
The following files are used by herbstluftwm:

  - 'autostart', see section <<AUTOSTART,*AUTOSTART FILE*>>.

EXIT STATUS
-----------
Returns *0* on success. Returns +EXIT_FAILURE+ if it cannot startup or if
'wmexec' fails.

BUGS
----
See the *herbstluftwm* distribution BUGS file.

COMMUNITY
---------
Feel free to join the IRC channel '#herbstluftwm' on 'irc.freenode.net'.

AUTHOR
------
*herbstluftwm* was written by Thorsten Wißmann. All contributors are listed in
the *herbstluftwm* distribution AUTHORS file.

RESOURCES
---------
Homepage: <http://herbstluftwm.org>

Github page: <http://github.com/herbstluftwm/herbstluftwm>

Patch submission and bug reporting:

    hlwm@lists.herbstluftwm.org

COPYING
-------
Copyright 2011-2014 Thorsten Wißmann. All rights reserved.

This software is licensed under the "Simplified BSD License". See LICENSE for
details.

// vim: tw=80 ft=asciidoc