- buster 0.7.1-2
- buster-backports 0.9.0-1~bpo10+1
- testing 0.9.2-1
- unstable 0.9.2-1
- experimental 0.9.3-1
HERBSTLUFTWM(1) | HERBSTLUFTWM(1) |
NAME¶
herbstluftwm - a manual tiling window manager for XSYNOPSIS¶
herbstluftwm [OPTION ...]DESCRIPTION¶
Starts the herbstluftwm window manager on DISPLAY. It also listens for calls from herbstclient(1) and executes them. The list of available COMMANDS is listed below.OPTION can be:
-c, --autostart PATH
-v, --version
-l, --locked
--verbose
This manual documents the scripting and configuration interface. For a more verbose introduction see 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:It shows some clients and arranges them. The current layout algorithms are:
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¶
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:
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 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:
COMMANDS¶
herbstluftwm is controlled by internal commands, which can be executed via herbstclient(1) or via keybindings.quit
reload
version
echo [ARGS ...]
true
false
list_commands
list_monitors
list_rules
list_keybinds
Warning
Tabs within command parameters are not escaped!
lock
unlock
keybind KEY COMMAND [ARGS ...]
keyunbind KEY|-F|--all
mousebind BUTTON ACTION [COMMAND ...]
mouseunbind
spawn EXECUTABLE [ARGS ...]
wmexec [WINDOWMANAGER [ARGS ...]]
chain SEPARATOR [COMMANDS ...]
chain , add foo , use foo
chain .-. lock .-. rotate .-. rotate .-. rotate .-. unlock
chain , add foo, use foo
chain . add foo , use foo
and SEPARATOR [COMMANDS ...]
or SEPARATOR [COMMANDS ...]
! COMMAND
try COMMAND
silent COMMAND
focus_nth INDEX
cycle [DELTA]
cycle_all [--skip-invisible] [DIRECTION]
cycle_frame [DIRECTION]
cycle_layout [DELTA [LAYOUTS ...]]
set_layout LAYOUT
close WINID
close_or_remove
close_and_remove
split ALIGN [FRACTION]
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:
focus [-i|-e] DIRECTION
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 └─────┘└─────┘
focus_edge [-i|-e] DIRECTION
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
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
bring WINID
resize DIRECTION FRACTIONDELTA
shift_edge [-i|-e] DIRECTION
shift [-i|-e] DIRECTION
shift_to_monitor MONITOR
remove
rotate
set NAME VALUE
get NAME
toggle NAME
cycle_value NAME VALUES ...
cycle_monitor [DELTA]
focus_monitor MONITOR
add TAG
use TAG
use_index INDEX [--skip-visible]
use_previous
merge_tag TAG [TARGET]
rename OLDTAG NEWTAG
move TAG
move_index INDEX [--skip-visible]
lock_tag [MONITOR]
unlock_tag [MONITOR]
disjoin_rects RECTS ...
300x150+300+250 600x250+0+0 300x150+0+250 300x150+600+250 600x250+300+400
┌──────┐ ┌──────┐ │ │ └──────┘ │ ┌───┼───┐ ┌─┐┌───┐┌──┐ │ │ │ │ disjoin │ ││ ││ │ └──┼───┘ │ ─────────> └─┘└───┘└──┘ │ │ ┌───────┐ └───────┘ └───────┘
set_monitors RECTS ...
detect_monitors -l|--list|--no-disjoin
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]]
remove_monitor MONITOR
move_monitor MONITOR RECT [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]
raise_monitor [MONITOR]
rename_monitor MONITOR NAME
stack
monitor_rect [[-p] MONITOR]
pad MONITOR [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]
list_padding [MONITOR]
layout [TAG [INDEX]]
An example output is:
╾─┐ horizontal 50% selection=1 ├─╼ vertical: 0xe00009 └─┐ vertical 50% selection=0 ├─╼ vertical: 0xa00009 [FOCUS] └─╼ vertical: 0x1000009
dump [TAG [INDEX]]
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
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 all commands beginning with m
prints all settings beginning with fra that can be toggled
complete_shell POSITION [COMMAND ARGS ...]
emit_hook ARGS ...
tag_status [MONITOR]
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]
rule [[--]FLAG|[--]LABEL|[--]CONDITION|[--]CONSEQUENCE ...]
unrule LABEL|--all|-F
fullscreen [on|off|toggle]
pseudotile [on|off|toggle]
object_tree [PATH]
attr [PATH [NEWVALUE]
get_attr ATTRIBUTE
set_attr ATTRIBUTE NEWVALUE
new_attr [bool|color|int|string|uint] PATH
remove_attr PATH
substitute IDENTIFIER ATTRIBUTE COMMAND [ARGS ...]
Prints the title of the currently focused window.
sprintf IDENTIFIER FORMAT [ATTRIBUTES ...] COMMAND [ARGS ...]
Prints the title of the currently focused window prepended by title=.
Moves the next client that appears to the tag that is currently focused.
Tells which tag is focused and how many tags there are
Prints somelongstring three times, separated by spaces.
mktemp [bool|int|string|uint] IDENTIFIER COMMAND [ARGS ...]
compare ATTRIBUTE OPERATOR VALUE
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
setenv NAME VALUE
unsetenv NAME
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)
frame_padding (Integer)
window_gap (Integer)
snap_distance (Integer)
snap_gap (Integer)
mouse_recenter_gap (Integer)
frame_border_active_color (String/Color)
frame_border_normal_color (String/Color)
frame_border_inner_color (String/Color)
frame_bg_active_color (String/Color)
frame_bg_normal_color (String/Color)
frame_bg_transparent (Integer)
frame_transparent_width (Integer)
frame_border_width (Integer)
frame_border_inner_width (Integer)
focus_crosses_monitor_boundaries (Integer)
raise_on_focus (Integer)
raise_on_focus_temporarily (Integer)
raise_on_click (Integer)
window_border_width (Integer)
window_border_inner_width (Integer)
window_border_active_color (String/Color)
window_border_normal_color (String/Color)
window_border_urgent_color (String/Color)
window_border_inner_color (String/Color)
always_show_frame (Integer)
frame_active_opacity (Integer)
frame_normal_opacity (Integer)
default_frame_layout (Integer)
default_direction_external_only (Integer)
gapless_grid (Integer)
smart_frame_surroundings (Integer)
smart_window_surroundings (Integer)
focus_follows_mouse (Integer)
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)
monitors_locked (Integer)
swap_monitors_to_get_tag (Integer)
auto_detect_monitors (Integer)
tree_style (String)
X-.root #-. child 0 | #-* child 01 | +-* child 02 +-. child 1 : #-* child 10 : +-* child 01
Useful values for tree_style are: ╾│ ├└╼─┐ or -| |'--. or ╾│ ├╰╼─╮.
wmname (String)
pseudotile_center_threshold (Int)
update_dragged_clients (Int)
verbose (Int)
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 CONSEQUENCEs). A rule can be defined with this command:rule [[--]FLAG|[--]LABEL|[--]CONDITION|[--]CONSEQUENCE ...]
Each rule consists of a list of FLAGs, CONDITIONs, CONSEQUENCEs 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:
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:
Valid properties are:
instance
class
title
pid
maxage
windowtype
windowrole
Each CONSEQUENCE consists of a NAME=VALUE pair. Valid NAMES are:
tag
monitor
focus
switchtag
manage
index
pseudotile
ewmhrequests
ewmhnotify
fullscreen
hook
keymask
A rule’s behaviour can be configured by some special FLAGS:
Examples:
Moves all Netscape instances to tag 6, but doesn’t give focus to them.
Moves all clients to tag 2, if their class does not end with term or Term.
Insert all Thunderbird instances in the tree that has no focus and there in the first child.
Sets focus to new dialogs which set their _NET_WM_WINDOW_TYPE correctly.
WINDOW IDS¶
Several commands accept a window as reference, e.g. close. The syntax is as follows: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:
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:
u - count | number of tags |
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 |
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 |
u - count | number of monitors |
s - name | its name |
i - index | its index |
s - tag | the tag currently viewed on it |
b - lock_tag |
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.
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 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
tag_changed TAG MONITOR
focus_changed WINID TITLE
window_title_changed WINID TITLE
tag_flags
tag_added TAG
tag_removed TAG
urgent [on|off] WINID
rule NAME WINID
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
reload
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: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¶
As far as possible, herbstluftwm tries to be EWMH compliant. That includes:ENVIRONMENT VARIABLES¶
DISPLAYFILES¶
The following files are used by herbstluftwm: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.orgGithub 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.
2018-08-21 | herbstluftwm 0.7.1 |