HERBSTLUFTWM(1)
๐ okay bestie, it's herbstluftwm time ๐
This is the herbstluftwm(1) manual, rewritten so it actually makes sense. Grab a snack, we're doing window-manager lore. ๐
โจ NAME โจ
herbstluftwm โ a manual tiling window manager for X. Periodt.
๐ธ SYNOPSIS ๐ธ
herbstluftwm [OPTION ...]
๐ DESCRIPTION ๐
So herbstluftwm starts the herbstluftwm window manager on DISPLAY. It also listens for calls from herbstclient(1) and executes them. The full list of available COMMANDS is literally below, don't worry.
OPTION can be:
-v,--versionโ print version and exit.-h,--helpโ print a short help and exit.-c,--autostartPATHโ usePATHas the autostart file instead of the one in$XDG_CONFIG_HOME.--replaceโ replace the existing window manager.-l,--lockedโ initially set themonitors_lockedsetting to1. WARNING: this keeps herbstluftwm locked until theunlockcommand is invoked (usually by the autostart). If--lockedis activated but the autostart does not invokeunlock(or if its invokation is unreachable because of a blocking command before), then herbstluftwm stays locked, resulting in frozen state. Only use with care!--exit-on-xerrorโ make herbstluftwm exit whenever xlib reports an error. This may only be activated for automated testing and never for actual sessions.--no-transparencyโ disable true transparency.--no-tag-importโ do not preserve the tags (virtual desktops) from a previous running window manager.--verboseโ print verbose information to stderr. This can be switched at run-time by theverbosesetting.
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:
- Frame contains windows:
It shows some clients and arranges them. The available layout algorithms are:
verticalโ clients are placed below each other.horizontalโ clients are placed next to each other.maxโ all clients are maximized in this frame.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, and 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. Cute, right? ๐ธ
๐ 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 interprets the index string character by character 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.@โ select the frame having the focus. In contrast to., this passes multiple layers all down to the focused leaf of the frame tree.pโ select the parent tree.eโ finds a suitable empty frame: if the focused frame is not empty, this selects the closest frame that is empty (in any subtree).
For example:
- An empty string refers to the root frame.
00refers to the first subtree of the first subtree of the root frame.1erefers to the first empty frame in the second subtree./@refers to the focused frame within the unfocused "half" of the frame tree.@p/refers to the sibling of the 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. Very main-character energy, honestly. โจ
๐ 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_monitorscommand. - by its relative index: a
+or-followed by a delta, e.g.:+3. - by its relative position to the focused monitor.
-ldenotes the monitor left of the focused monitor,-rright of,-uabove of, and-dbelow of, respectively. - by
""(an empty string) which represents the current monitor. - by its name.
๐ฅ COMMANDS ๐ฅ
herbstluftwm is controlled by internal commands, which can be executed via herbstclient(1) or via keybindings. Okay, here's the whole command menu:
quitโ Quits herbstluftwm.reloadโ Executes the autostart file.versionโ Prints the version of the running herbstluftwm instance.echo [ARGS ...]โ Prints all givenARGSseparated 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.help [OBJECT|ATTRIBUTE]โ Print help on a given object or attribute. For example:help clients.focushelp monitorshelp types.color
list_commandsโ Lists all available commands.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!
list_clients [--tag=TAG|--monitor=MONITOR] [--frame=FRAME_PATH|--floating|--tiling] [--title]โ Lists the window ids of all clients on the givenTAGorMONITOR(or the current if unspecified). In addition to that, one can restrict to clients in a specific frame (--frame=) or to tiled or floated clients. The output is one line per client; if--titleis given, then in addition to every clientโs window id, its window title is printed in the same line.lockโ Increases themonitors_lockedsetting. 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 themonitors_lockedsetting. Ifmonitors_lockedis changed to0, then all monitors are repainted again. See also:lock.keybind KEY COMMAND [ARGS ...]โ Adds a key binding. If there is already a binding for thisKEY, it will be overwritten. WhenKEYis pressed, the internalCOMMAND(with itsARGS) 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 (seekeysymdef.hfor a list of keys). Modifiers and the key are concatenated with-or+as separator. IfKEYis prefixed withRelease-then the keybinding is only active during the corresponding key release event: that is, in order to run the key binding forRelease-Mod1-Shift-pone needs to first pressMod1-Shift-pand then releasep. Examples:keybind Mod4+Ctrl+q quitkeybind Mod4-Shift-d attr clients.focus.decorated togglekeybind Mod1-Shift-space cycle_layout -1keybind Release-Mod4-Shift-p spawn scrottakes a screenshot when thepis released whileMod4andShiftare still pressed.
keyunbind KEY|-F|--allโ Removes the key binding forKEY. The syntax forKEYis defined inkeybind. If-For--allis given, then all key bindings will be removed.mousebind BUTTON ACTION [COMMAND ...]โ Adds a mouse binding for the floating mode. WhenBUTTONis pressed, the specifiedACTIONwill be performed.BUTTONhas a similar syntax to theKEYargument ofkeybind: It consists of a list of modifiers (separated by-or+, valid modifiers are listed in the description ofkeybind) and exactly one button name:B1orButton1B2orButton2- ...
B9orButton9
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 specifiedCOMMANDwhileclient.draggedlinks to the client on which theBUTTONhas been performed.
While an ACTION is performed, client.dragged is the client which is dragged. E.g.:
mousebind Mod1-Button3 zoommousebind Mod1-B4 call substitute WID clients.dragged.winid spawn transset-df --inc -i WID 0.05mousebind Mod1-B5 call substitute WID clients.dragged.winid spawn transset-df --dec -i WID -m 0.2 0.05
drag WINID ACTIONโ Starts dragging the specified client windowWINIDwith the specifiedACTION(seemousebind). E.g.drag '' resizestarts resizing the focused window.mouseunbindโ Removes all mouse bindings.
spawn EXECUTABLE [ARGS ...]
Okay so this one spawns an EXECUTABLE with its ARGS. For the full deets, see man 3 execvp. Example:
spawn xterm -e man 3 execvp
wmexec [WINDOWMANAGER [ARGS ...]]
Executes the WINDOWMANAGER with its ARGS. This is lowkey iconic for switching the window manager in the running session without restarting the session. If no WINDOWMANAGER is given, or itโs invalid, 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 be any word and is only 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. no cap, itโs the โplease donโt fail the whole chainโ bestie.
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, or cycles through the clients in the floating layer if that is focused. 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 non-minimized windows and frames on the current tag. DIRECTION = 1 means forward (default value), DIRECTION = -1 means backward, DIRECTION = 0 has no effect. If there are multiple windows within one frame, then it acts similar to the cycle command. If --skip-invisible is given, then this only cycles through all visible windows and skips invisible windows in the max layout (the flag only affects invisible windows in the max layout; minimized windows are always skipped). After each focus change, 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 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 -1cycle_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 of layout algorithms above.
close WINID
Closes the specified window gracefully or the focused window if none is given explicitly. See the section on WINDOW IDS for how to reference a certain window.
close_or_remove
Closes the focused window or removes the current frame if no window is focused. In floating mode, this acts as the close command.
close_and_remove
Closes the focused window and removes the current frame if no other window is present in that frame. In floating mode, this acts as the close command.
split ALIGN [FRACTION [FRAMEINDEX]]
Splits the focused frame (or the frame specified by FRAMEINDEX, see the section frame index) into two subframes with a specified FRACTION between 0 and 1 which defaults to 0.5. ALIGN is one of:
topbottom(=vertical)leftright(=horizontal)explodeauto(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 focused frame will stay focused. One special ALIGN mode is explode, which splits the frame in such a way that the window focus, window sizes, and positions are kept as much as possible (so the default FRACTION is not always 0.5, unlike for the other ALIGN modes). Example:
split explodesplit bottom 0.5split horiz 0.3split vertical 0.5split hsplit top 0.2 ''(splits the root frame)
focus [-i|-e|--level=LEVEL] DIRECTION
Moves the focus from the current frame to the next frame or client in DIRECTION, which is in:
l[eft]r[ight]u[p]d[own]
If there is no client within this frame or LEVEL is frame, then the next frame in the specified DIRECTION will be focused. If LEVEL is visible or default_direction_external_only is unset, then the next client in DIRECTION can also be within the same frame, but has to be visible. For tabs LEVEL, the next client may be hidden in a tabbed_max layout. With all, any client within a max layout maybe selected before focusing the next frame. The flag -i is an alias for --level=visible and -e for --level=frame.
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: H,0 Screen: โโโโโโโโโโโโโโ (before)
โฑ โฒ โ B โโ C โ
โฑ โฒ โโโโโโโโโโโโโโ
V,1 V,0 โโโโโโโโโโโโโโ
โฑ โฒ โฑ โฒ โ A* โโ D โ
B A* C D โโโโโโโโโโโโโโ
Tree: H,1 Screen: โโโโโโโโโโโโโโ (after focus right)
โฑ โฒ โ B โโ C* โ
โฑ โฒ โโโโโโโโโโโโโโ
V,1 V,0 โโโโโโโโโโโโโโ
โฑ โฒ โฑ โฒ โ A โโ D โ
B A 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 managed or unmanaged window. Managed windows are only moved within the tagโs stack (as reported by the stack command), and unmanaged windows are raised globally, i.e. are raised above all managed windows. See the section on WINDOW IDS on how to reference a certain window. Its result is only visible for floating windows and unmanaged windows.
lower WINID
Lowers the specified managed or unmanaged window, analogously to the raise command: managed windows are lowered within the stack of floating windows (with no effect for tiled windows) and unmanaged windows are moved below all managed windows (for example, it can be used to lower desktop windows).
jumpto WINID
Puts the focus to the specified window. See the section on WINDOW IDS on how to reference a certain window.
bring WINID
Moves the specified window to the current frame and focuses it. Floating windows are brought to the current tag, but keep their floating state. See the section on WINDOW IDS on how to reference a certain window.
resize DIRECTION [FRACTIONDELTA]
Changes the size of the focused frame in the specified DIRECTION by FRACTIONDELTA (which defaults to 0.02 if none is supplied). DIRECTION behaves as specified at the focus command. If a floating window is focused, it grows towards next edge, i.e. either the edge of the next window or the monitor edge in the specified DIRECTION (FRACTIONDELTA is ignored in that case). Example:
resize right +0.05resize 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|--level=LEVEL] DIRECTIONโ moves the focused window to the next frame in whatever DIRECTION you picked ๐ . The DIRECTIONS and the-i/-e/--level=LEVELparams work exactly like they do at thefocuscommand (go look at that one, bestie). If the focused client is floated instead of tiled, then the client gets shifted to the next window or to the screen edge instead ๐ฆ. And if the window can't be moved and the settingfocus_crosses_monitor_boundariesis activated, then the window gets moved to the monitor in the specified DIRECTION. slay.shift_to_monitor MONITORโ moves the focused window to the tag on the specified MONITOR. Wanna know how to address a monitor? Peek at the MONITORS section ๐removeโ removes the focused frame and merges its windows into its closest neighbour frame ๐rotateโ rotates the layout on the focused tag counterclockwise by 90 degrees. Heads up though: this only messes with the alignment of frames, NOT the content of them ๐ฅmirror [vertical|horizontal|both]โ mirrors the layout on the focused tag vertically, horizontally, or both; the default is horizontal. Same deal: this only manipulates the alignment of frames, not the content of them โจset NAME VALUEโ sets the specified setting NAME to VALUE. For boolean settings the allowed values areonortruefor on,offorfalsefor off, andtoggleto toggle its value ๐. Every setting is listed in the section below, iykyk.get NAMEโ prints the value of setting NAME. All settings are listed in the section below ๐toggle NAMEโ toggles the setting NAME if it's a boolean setting ๐ซถcycle_value PATH VALUES ...โ cycles the value of the attribute PATH through VALUES. Like: it searches for the first occurrence of the current value in VALUES and changes the value to the next one in the list, or to the first one if the end is reached or if the current value wasn't found at all ๐. For compatibility reasons, PATH can also be the name of a setting. Examples, bestie:cycle_value settings.frame_gap 0 5 10 15cycle_value theme.active.inner_color red green blue- the command
cycle_layout +1is equivalent tocycle_value tags.focus.tiling.focused_frame.algorithm
cycle_monitor [DELTA]โ cycles the focused monitor by DELTA. DELTA defaults to1๐ซfocus_monitor MONITORโ puts focus on the specified monitor. See the MONITORS section for how to address a monitor ๐add TAGโ creates a new empty tag named TAG ๐use TAGโ switches the focused monitor to the 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. And if--skip-visibleis passed and INDEX is relative, then tags that are already visible on a monitor get 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 the tag named TAG and moves all its windows to tag TARGET. If TARGET is omitted, the focused tag gets used ๐rename OLDTAG NEWTAGโ renames the 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 foruse_index: if INDEX starts with+or-, then it's treated as relative. And if--skip-visibleis passed along with a relative index, then already-visible tags get skipped ๐lock_tag [MONITOR]โ locks the tag switching on the specified monitor. If no argument is given, the currently focused monitor is used ๐. When tag switching is disabled for a monitor, the commandsuseanduse_indexhave no effect when executed there โ fr fr, nothing happens. Whenswap_monitors_to_get_tagis enabled, switching to a tag that's located on a locked monitor switches to that monitor instead of stealing the tag from there ๐. The lock state of a monitor is shown by[LOCKED]in thelist_monitorsoutput ๐unlock_tag [MONITOR]โ re-enables tag switching on the specified monitor. If no argument is given, the currently focused monitor is used ๐. This is the reverse operation tolock_tagand has no further side effects besides removing the lock โจdisjoin_rects RECTS ...โ takes a list of rectangles and splits them into smaller pieces until all rectangles are disjoint; the resulting rectangles get printed line by line ๐. Heads up: this command does not modify the current list of monitors! So it's lowkey useful in combination with theset_monitorscommand ๐ซถ- E.g.
disjoin_rects 600x400+0+0 600x400+300+250prints this:
- E.g.
300x150+300+250
600x250+0+0
300x150+0+250
300x150+600+250
600x250+300+400
- In the example above, two monitors get split into 5 monitors, which graphically means:
โโโโโโโโ โโโโโโโโ
โ โ โโโโโโโโ
โ โโโโโผโโโโ โโโโโโโโโโโโ
โ โ โ โ disjoin โ โโ โโ โ
โโโโผโโโโ โ โโโโโโโโโ> โโโโโโโโโโโโ
โ โ โโโโโโโโโ
โโโโโโโโโ โโโโโโโโโ
set_monitors RECTS ...โ sets the list of monitors exactly to the list of given rectangles, like this ๐ธ:- The i'th existing monitor gets moved to the i'th given RECT
- New monitors get created if there are more RECTS than monitors
- Existing monitors get deleted if there are more monitors than RECTS
detect_monitors -l|--list|--list-all|--no-disjoinโ sets the list of monitors to the physically available monitors ๐ฅ๏ธ. If both Xinerama and xrandr are missing, it falls back to one monitor across the entire screen. If the detected monitors overlap, they get split into more monitors that are disjoint but cover the same area, usingdisjoin_rectsโจ
If -l or --list is passed, the list of rectangles of detected physical monitors gets printed. So hc detect_monitors is equivalent to the bash command hc set_monitors $(hc disjoin_rects $(hc detect_monitors -l)) ๐ซ
If --list-all is passed, then it prints which multimonitor detection (xinerama, xrandr) has which set of physical monitors ๐
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 โ that's a real rule, bestie. RECT is a string of the formWxHยฑXยฑY. If no or an empty TAG is given, then any free/empty tag gets chosen, depending on themonitors.tag_selection_strategyattribute. And if a NAME is given, you can reference 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 inadd_monitor. If no pad or an empty pad is given, it's 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 thetree_stylesetting ๐จmonitor_rect [[-p] MONITOR]โ prints the rectangle of the specified monitor in the format:X Y W H๐. If no MONITOR orcuris given, then the current monitor is used. If-pis supplied, then the remaining rect without the pad around this monitor gets printed ๐pad MONITOR [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]โ sets the pad of the specified monitor to the specified padding. If no padding or an empty padding is given, it's not changed ๐list_padding [MONITOR]โ lists the padding of the specified monitor, or of the currently focused monitor if no monitor is given ๐layout [TAG [INDEX]]โ prints the layout of the frame with INDEX on TAG, in a nice tree style ๐ณ. Its style is defined by thetree_stylesetting. 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 the 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 thelayoutcommand but in a machine readable format ๐ค. Its output can be read back with theloadcommand ๐
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 into the specified TAG, or the current tag if no TAG is given ๐ฅ
Caution โ ๏ธ โ LAYOUT is exactly one parameter. If you're calling it manually from your shell or from a script, QUOTE IT PROPERLY! No cap, this will bite you ๐ญ
complete POSITION [COMMAND ARGS ...]โ prints the result of tab completion for the partial COMMAND with optional ARGS โจ. You usually don't need this, because there's already tab completion for bash, zsh and fish ๐. 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 likecompletewith the following extras, which are useful for completion on posix shells ๐:- Escape sequences get removed in COMMAND and ARGS ๐ง
- A space gets appended to each full completion result โฃ
- Special characters get escaped in the output ๐
emit_hook NAME ARGS ...โ emits a custom hook NAME to all idling herbstclients ๐ขtag_status [MONITOR]โ prints a tab-separated list of every tag on the monitor with index MONITOR. No MONITOR index? Then it uses the focused monitor, obvs. Each tag name gets a single char slapped on the front to tell you its whole vibe:.โ 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 put a tab in one of your tag names, tag_status is probably gonna be straight-up useless for you. Like, bestie, why. ๐ญ
floating [[TAG] on|off|toggle|status]โ flips the specified TAG into floating or tiling mode, or just prints its current status if you're nosy. No TAG given? It uses the current tag. No argument at all? Floating mode gets toggled. And if you passstatus, it printsonoroffdepending on the floating state of TAG. โจrule [[--]FLAG|[--]LABEL|[--]CONDITION|[--]CONSEQUENCE ...]โ defines a rule that gets applied to every new client that shows up. The whole behaviour thing is described in the RULES section, go peek there.unrule LABEL|--all|-Fโ removes all rules named LABEL. If you pass--allor-F, then literally every rule gets removed. bye y'all ๐apply_rules WINID|--allโ applies the rules to the window WINID. Pass--alland the rules get applied to all clients.apply_tmp_rule WINID|--all [RULEDESCRIPTION...]โ applies the rule RULEDESCRIPTION to one particular client WINID, or to all clients if you pass--all, without adding the rule to the rule list. The RULEDESCRIPTION is a rule made of conditions and consequences, exactly like you'd pass to therulecommand as described in the RULES section. This is your little test kitchen, so you can try rules before committing to them. Runningapply_tmp_ruleonly applies the particular rule given in the arguments and ignores the existing rules. ๐งชfullscreen [on|off|toggle]โ sets or toggles the fullscreen state of the focused client. No argument? Fullscreen mode gets toggled.pseudotile [on|off|toggle]โ sets or toggles the pseudotile state of the focused client. So like, if a client is pseudotiled, then in tiling mode the client is only moved but not resized โ the client size stays the floating size. The only reason to resize the client is to make sure it fits into its tile. No argument given? Pseudotile mode gets toggled. ๐ฆobject_tree [PATH]โ prints the tree of objects. If you give it the object path PATH, only the subtree starting at PATH gets printed. See the OBJECTS section for more, iykyk.attr [PATH [NEWVALUE]โ prints the children and attributes of the given object addressed by PATH. If PATH is an attribute, then it prints the attribute value. And if NEWVALUE is given, it assigns NEWVALUE to the attribute given by PATH. See the OBJECTS section for the details. ๐get_attr ATTRIBUTEโ prints the value of the specified ATTRIBUTE, as described in the OBJECTS section.set_attr ATTRIBUTE NEWVALUEโ assigns NEWVALUE to the specified ATTRIBUTE, as described in the OBJECTS section.attr_type ATTRIBUTEโ prints the type of the specified ATTRIBUTE.new_attr bool|color|int|string|uint PATH [VALUE]โ creates a new attribute with the name and in the object specified by PATH. Its type is whatever the first argument says. Heads up: the attribute name has to begin withmy_. If VALUE is supplied, then it gets written to the attribute (and if that fails, the attribute still remains). ๐ธwatch PATHโ watches the value of the given attribute PATH. Whenever the value changes from OLDVALUE to NEWVALUE, a hook gets emitted:
attribute_changed PATH OLDVALUE NEWVALUE
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 with the value of the ATTRIBUTE. Note that the COMMAND also gets replaced by the attribute value if it equals IDENTIFIER. The replaced command with its arguments then gets executed. Example:substitute MYTITLE clients.focus.title echo MYTITLEโ prints the title of the currently focused window. ๐
sprintf IDENTIFIER FORMAT [FORMATARG ...] COMMAND [CMDARGS ...]โ replaces all exact occurrences of IDENTIFIER in COMMAND and its CMDARGS with the string specified by FORMAT. The FORMAT string may contain several placeholders, similar to theprintf(1)command:%sinserts an attribute value whose path is given by the string value of the next FORMATARG%c("constant") inserts the next FORMATARG without modification%{ATTR}inserts the current value of the attribute ATTR. The path ATTR can itself contain format placeholders. This is lowkey iconic because you can compose attribute paths at run time, e.g. in aforeachloop.%%stands for a plain%
The replaced command with its arguments then gets executed. Examples:
sprintf STR title=%s clients.focus.title echo STRโ prints the title of the currently focused window prepended bytitle=.sprintf X "%c %s tags" "there are" tags.count echo Xโ printsthere are N tagswithNreplaced by the number of tags.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โ printssomelongstringthree times, separated by spaces.sprintf VALUE "%{%c.client_count}" tags.0 echo VALUEโ prints the number of clients on the tag with index 0.foreach --filter-name="[0-9]*" T tags. sprintf S "%{%c.client_count}" T echo T Sโ prints the number of clients for each tag.substitute X tags.count sprintf Y "number=%c" X echo Yโ has the same output assprintf Y "number=%s" tags.count echo Y(note how the%cchanges to%s). ๐คฏ
foreach IDENTIFIER OBJECT [--recursive] [--unique] [--filter-name=REGEX] COMMAND [ARGS ...]โ for each child of the given OBJECT, the COMMAND gets called with its ARGS, where the IDENTIFIER is replaced by the path of the child. The options are:--filter-name=REGEXโ consider children whose name match the specified REGEX--uniqueโ do not print duplicates (some objects can be reached via multiple paths, such asclients.focus)--recursiveโ print OBJECT and all its children of arbitrary depth in breadth-first search order. This implicitly activates--unique.
The exit code is the exit code of the command executed last. Examples:
foreach T tags.by-name. echo Tโ prints:
tags.by-name.1
tags.by-name.2
tags.by-name.3
[...]
- Note that
foreachonly iterates over children, but not over attributes, soforeach S settings echo Sprints nothing, since thesettingsobject has only attributes but no child objects. foreach C clients. echo Cprints the object paths of all clients, but the focused client twice, because it's mentioned inclients.twice: by window id and asclients.focus.foreach F tags.focus.tiling.root. --recursive echo Fprints the object paths of all frames on the focused tag.
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 the path of the temporary attribute. The replaced command with its arguments then gets executed. 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 returns0, else1. The operators are:=: ATTRIBUTE's value equals VALUE!=: ATTRIBUTE's value does not equal VALUEle: ATTRIBUTE's value<=VALUElt: ATTRIBUTE's value<VALUEge: ATTRIBUTE's value>=VALUEgt: 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 wanna 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โ sets the value of the environment variable NAME to VALUE. See theexportcommand for a convenience wrapper.unsetenv NAMEโ unsets the environment variable NAME.export NAME=VALUEโ sets the value of the environment variable NAME to VALUE. The syntax is the same as forexportin unix shells (notice there's a=in there). Intuitively: if you forgot to runexport FOO=BARbefore starting herbstluftwm, you can runherbstclient export FOO=BARfrom within your herbstluftwm session for the same effect. Theexportcommand is the same as thesetenvcommand with different syntax. ๐ซถdebug_css [FLAGS]โ ok so this command exists solely for testing herbstluftwm; it has no use in normal hlwm sessions. Moreover, the interface of this command may change in incompatible ways. Consider yourself warned ๐. The command performs various operations, specified by the optional FLAGS:--stylesheet=CSSโ specify some stylesheet that is possibly used in one of the other commands--print-cssโ print the stylesheet in some normalized form--tree=TREEโ a dom-style tree specification, where the syntax of a tree starts with(and ends with). In between, the tree contains a space-separated list of class names and subtrees.--print-treeโ print the tree specification of TREE again--pretty-client-tree=CLIENTโ for the given CLIENT, print the tree of its widgets together with the classes each widget has. Each class is preceeded with a dot.in the same way as in a css selector. ๐จ
--query-tree-indices=SELECTORโ prints the tree indices (analogously to frame indices) of those nodes that match the given css-styleSELECTOR. ๐--compute-style=INDEXโ computes the box style of the node in aboveTREEthat has the tree indexINDEX. โจ
๐ RULES ๐
Okay bestie, rules are how you change default properties for certain clients when they appear โ or when the apply_rules command is called. Each rule matches against a certain subset of all clients and defines a set of properties for them (called CONSEQUENCEs). You define a rule with this:
rule [[--]FLAG|[--]LABEL|[--]CONDITION|[--]CONSEQUENCE ...]
Each rule is 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, iykyk.)
Each rule can get 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 gets 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 integerLABEL. Default labels can be captured with theprintlabelflag.
When a new client appears, herbstluftwm tries to apply each rule to this new client like this: if each CONDITION of the rule matches against the client, then every CONSEQUENCE is executed. (If there are no conditions given, then this rule is executed for each client.) ๐
Each CONDITION is a property name, an operator and a value. The valid operators are:
~โ matches if clientโs property is matched by the regex value.=โ matches if clientโs property string is equal to value.
Valid properties are:
instanceโ the first entry in clientโsWM_CLASS.classโ the second entry in clientโsWM_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_PIDto the pid itself.pgidโ this clientโs process group id. Since the pgid of a window is derived from its pid, the same restrictions apply as above.maxageโ matches if the age of the rule measured in seconds does not exceed value. This condition only can be used with the=operator. Ifmaxagealready 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_TYPEproperty of a window. If_NET_WM_WINDOW_TYPEhas multiple entries, then only the first entry is used here.windowroleโ matches theWM_WINDOW_ROLEproperty of a window if it is set by the window.fixedsize(no parameter) โ matches if the window does not allow being resized (i.e. if the minimum size matches the maximum size). This condition does not take a parameter. Example:
hc rule fixedsize floating=on
Each CONSEQUENCE is a NAME=VALUE pair. Valid NAMEs are:
tagโ moves the client to tagVALUE.monitorโ moves the client to the tag on monitorVALUE. If thetagconsequence was also specified, andswitchtagis set for the client, move the client to that tag, then display that tag on monitorVALUE. If thetagconsequence was specified, butswitchtagwas not, ignore this consequence.focusโ decides whether the client gets the input focus in its tag. The default isoff.VALUEis a boolean (onoroff).switchtagโ iffocusis activated and the client is put to a not focused tag, thenswitchtagtells 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 ifswap_monitors_to_get_tagis activated.VALUEis a boolean (onoroff).manageโ decides whether the client will be managed or not. The default ison.VALUEis a boolean (onoroff).indexโ moves the window to a specified index in the tree.VALUEis a frame index.floatingโ sets the floating state of the client.VALUEis a boolean.pseudotileโ sets the pseudotile state of the client.VALUEis a boolean.stickyโ sets the sticky attribute of the client.VALUEis a boolean.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.VALUEis a boolean; it defaults toon.ewmhnotifyโ sets whether hlwm should let the client know aboutEMWHchanges (currently only the fullscreen state). If this is set, applications do not change to their fullscreen-mode while still being fullscreen.VALUEis a boolean, it defaults toon.fullscreenโ sets the fullscreen flag of the client.VALUEis a boolean.hookโ emits the custom hookrule VALUE WINIDwhen this rule is triggered by a new window with the idWINID. This consequence can be used multiple times, which will cause a hook to be emitted for each occurrence of ahookconsequence.keymaskโ sets the keymask for a client (see thekeymaskattribute documentation).keys_inactiveโ sets a regex that determines which key bindings are inactive for a client (see thekeys_inactiveattribute documentation).floatplacementโ changes the floating position of a window. TheVALUEcan be one of the following:nonedoes not change the placement at all.centercenters the window on the monitor.smarttries to place it with as little overlap to other floating windows as possible. If there are multiple options with the least overlap, then the position with the least overlap to tiling windows is chosen.topleft,topright,bottomleft,bottomrightmoves the window to the respective corner of the monitor but leaves a gap ofsettings.snap_gappixels.
floating_geometryโ sets the clientโsfloating_geometryattribute. TheVALUEis a rectangle, interpreted relatively to the monitor. Iffloatplacementis also specified for the client (possibly by another rule), then only the size of thefloating_geometryis used. In order to force the position from the geometry, it is necessary to addfloatplacement=none.
A ruleโs behaviour can be configured by some special FLAGs:
notโ negates the nextCONDITION.!โ same asnot.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, bestie โ these are iconic:
rule --class=Netscape --tag=6 --focus=off
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
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
rule class=Thunderbird index=/0
Inserts 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
rule --windowtype=_NET_WM_WINDOW_TYPE_DIALOG --focus=on
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:
- an empty string โ or missing argument โ references the currently focused window.
urgentreferences some window that is urgent.0xHEXIDโ whereHEXIDis some hexadecimal number โ references the window with hexadecimal X11 window idHEXID.longest-minimizedreferences the minimized window on the focused tag that has been minimized for the longest time.last-minimizedreferences the minimized window on the focused tag that has been minimized most recently.DECIDโ whereDECIDis some decimal number โ references the window with the decimal X11 window idDECID.
๐ OBJECTS ๐
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 an object, pass its PATH to attr:
$ herbstclient attr tags.
2 children:
by-name.
focus.
1 attributes:
.---- type
| .-- writable
V V
u - count = 9
$ herbstclient attr tags.focus.
0 children.
6 attributes:
.---- type
| .-- writable
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
bfor booleancfor colorifor integerrfor regexsfor stringufor unsigned integer
- if it is writable by the user:
wif yes,-else. - the name of the attribute
- its current value (only quoted for strings)
okay so to actually read one of these attribute things without the quotes being all extra about it, you address the attribute using the exact same syntax as you'd use for object paths, and then you 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
And when you wanna change a writable attribute value? You just pass the new value to attr or to set_attr, bestie:
$ 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
If you want the โจloreโจ on an attribute or an object, the help command is right there:
$ herbstclient help clients.focus
Literally just poke around and get a feel for what's in there ๐ซถ. The entry point is a root object that has the following child objects:
๐ธ autostart
string global_path = globalAutostartโ the path of the system-wide autostart, which gets used as a fallback.int last_status = 0โ the exit status of the last autostart run. ngl if the autostart is still running, then this status is the exit status of the previous autostart invocation.string path = autostartFromCmdLineโ a custom path to the user's autostart path. If it's empty, then the autostart in$XDG_CONFIG_HOMEor$HOMEis used.uint pid = 0โ the process id of the last autostart invocation. Even if the autostart isn't running anymore, its pid is still sitting here.bool running = falseโ whether the autostart process (withpid) is still running.
๐ฆ clients
The managed windows, periodt. For every (managed) window id there's an entry here.
draggedโ the object of a client which is currently being dragged by the mouse, if any. See the documentation of themousebindcommand for examples. For attributes and children, seeclients.focus.focusโ the focused client (only exists if a client is focused). a managed windowstring classโ the class of it (second entry inWM_CLASS)Rectangle content_geometryโ the geometry of the application content, i.e. not taking the decoration into account. Also, this is the last window geometry that was reported to the client application.bool decorated = trueโ whether window border and title are drawnRectangle decoration_geometryโ the geometry of the client, taking the window decoration into account. The position is the global window position, that is, relative to the top left corner of the entire screenbool ewmhnotify = trueโ if the client is told about its state via ewmhbool ewmhrequests = trueโ if ewmh requests are permitted for this clientbool floating = falseโ whether this client is set as a (single-window) floating client. If set, the client is floated above the tiled clients.bool floating_effectively = falseโ whether this client is in the floating state currently. This is the case if the client's tag is set to floating mode or if the client itself is set as floating. Its value is also indicated via the X11 propertiesHLWM_FLOATING_WINDOWandHLWM_TILING_WINDOW.Rectangle floating_geometry = 0โ the geometry of the client content if the client is in floating mode. The position is relative to the monitor and does not take the window decoration into account.bool fullscreen = falseโ whether this client covers all other windows and panels on its monitor.string instanceโ the instance of it (first entry inWM_CLASS)regex keymask = ""โ a regular expression that is matched against the string representation of all key bindings (as they are printed bylist_keybinds). While this client is focused, only bindings that match the expression will be active. Any other bindings will be disabled. The default keymask is an empty string (""), which does not disable any keybinding.regex keys_inactive = ""โ a regular expression that describes which keybindings are inactive while the client is focused. If a key combination is pressed and its string representation (as given bylist_keybinds) matches the regex, then the key press is propagated to the client.bool minimized = falseโ whether this client is minimized (also called iconified).int pgid = -1int pid = -1โ the process id of it (-1if unset).bool pseudotile = falseโ if activated, the client always has its floating window size, even if it is in tiling mode.bool sizehints_floating = trueโ if sizehints for this client should be respected in floating modebool sizehints_tiling = falseโ if sizehints for this client should be respected in tiling modebool sticky = falseโ whether this client is pinned to the monitor. This means that the client stays on its monitor, even when the monitor switches to another tag.string tagโ the name of the tag it's currently on.string title = ""โ its window titlebool urgent = falseโ the urgency state (also known as: demands attention). The focused client can not be urgent.bool visible = visible_alreadyโ whether this client is rendered currentlystring winid = ""โ its window id (as a hexadecimal number with0xprefix)parent_frameโ the frame containing this client if the client is tiled. For attributes and children, seetags.focus.tiling.root
๐ง monitors
Every monitor is a rectangular part of the screen on which a tag is shown, bestie. These monitors may or may not match the actual outputs. This has an entry INDEX for each monitor with index INDEX.
uint countTagSelectionStrategy tag_selection_strategy = any_unshownโ how to select a tag when a new monitor is created.any_unshown: select the first tag that is not shown on any monitoronly_empty: select the first empty tag that isn't shown, abort if none is availableprefer_empty: prefer an empty tag, but select any unshown tag if no empty tag is available
by-nameโ this has an entrynamefor every object with the given name. If an object has an empty name then it is not listed here.focusโ the focused monitor. The monitor is a rectangular part on the screen that holds precisely one tag at a time. The pad attributes reserve space on the monitor's edge for panels, so this space (given in number of pixels) is never occupied by tiled clients.Rectangle content_geometryโ the inner geometry of the monitor, i.e. the geometry with the pads deducted from all sides. This is the area floating and tiled client windows are placed.Rectangle geometry = rect_โ the outer geometry of the monitoruint index = 0โ the monitor's index (starts at index 0)bool lock_tag = falseโ if activated, then it it is not possible to switch this monitor to a different tag.string name = ""โ the monitor's name (can be empty)int pad_down = 0โ space for panels at the monitor's lower edgeint pad_left = 0โ space for panels at the monitor's left edgeint pad_right = 0โ space for panels at the monitor's right edgeint pad_up = 0โ space for panels at the monitor's upper edgestring tagโ the name of the tag viewed here
๐ panels
For every panel window, there's an entry with the panel's window id here.
uint countbool geometry_fallback = falseโ when auto-detecting panels: if a panel does not specify the amount of space it needs at the monitor edge, fall back to reserve the panel's geometry at the screen edge.0xWindowIDโ a panel is an unmanaged window that reserves space at the edge of the monitor it is on. The space depends on the_NET_WM_STRUTdefined by the panel. If it is however not defined explicitly, then the amount of reserved space is inferred from the window geometry.string classโ the window class (second entry ofWM_CLASS)Rectangle geometryโ the size and position of the windowstring instanceโ the window instance (first entry ofWM_CLASS)WindowID winid = winidโ the ID of the panel window
๐ settings
Settings configure the general behaviour of herbstluftwm and can be controlled via the set, get and toggle commands. The settings. object has an attribute for each setting. Many settings are wrappers around attributes and only remain for compatibility.
bool always_show_frame = falseโ DEPRECATED, useshow_frame_decorationsinstead. If set,show_frame_decorationswill be set toall(orfocusedif unset).bool auto_detect_monitors = falseโ if set,detect_monitorsis automatically executed every time a monitor is connected, disconnected or resized.bool auto_detect_panels = trueโ if set, EWMH panels are automatically detected and reserve space at the side of the monitors they are on (via pad attributes of each monitor). This setting is activated per default.bool default_direction_external_only = falseโ this setting controls the behaviour offocusandshiftif no-eor-iargument is given. If set, thenfocusandshiftchanges the focused frame even if there are other clients in this frame in the specifiedDIRECTION. Else, a client within current frame is selected if it is in the specifiedDIRECTION.LayoutAlgorithm default_frame_layout = verticalโ name of the layout algorithm, which is used if a new frame is created (on a new tag or by a non-trivial split). See above for the list of layout algorithms.string ellipsis = ...โ string to append when window or tab titles are shortened to fit in the available space.bool focus_crosses_monitor_boundaries = trueโ if set, commandsfocusandshiftcross monitor boundaries. If there is no client in the direction given tofocus, then the monitor in the specified direction is focused. Similarly, ifshiftcannot move a window within a tag, the window is moved to the neighbour monitor in the desired direction.bool focus_follows_mouse = falseโ okay so when this is set and a window gets focused by your mouse cursor just hovering over it, it actually becomes focused (this feature is also known as sloppy focus ๐ ). If it's unset, sorry bestie, you gotta click to change the window focus by mouse.
Real talk though: if another window gets hidden by the focus change (like when you've got pseudotiled windows hangin' out in max layout), then an extra click is required to change the focus. Not me finding that out the hard way ๐ญ
bool focus_stealing_prevention = trueโ when set, only pagers and taskbars are allowed to change the focus, periodt. Unset it and all applications can request a focus change. Chaos, but make it your choice โจint frame_active_opacity = 100โ focused frame opacity in percent. Needs a running compositing manager to actually do anything, fyi ๐ซถcolor frame_bg_active_color = blackโ the fill color of a focused frame.color frame_bg_normal_color = blackโ the fill color of an unfocused frame (it's only visible if non-focused frames are configured to be visible, seeshow_frame_decorations๐).bool frame_bg_transparent = falseโ if set, the background of frames is transparent. That means a rectangle is cut out from the inner such that only the frame border and a stripe of widthframe_transparent_widthcan be seen. Want real transparency? Useframe_active_opacityandframe_normal_opacity.color frame_border_active_color = redโ the border color of a focused frame. Iconic, red, love that for you ๐ฅcolor frame_border_inner_color = blackโ the color of the inner border of a frame.int frame_border_inner_width = 0โ the width of the inner border of a frame. Must be less thanframe_border_width, since it does not add to the frame border width but is a part of it. Sneaky little detail, iykyk.color frame_border_normal_color = blueโ the border color of an unfocused frame.int frame_border_width = 2โ border width of a frame.int frame_gap = 5โ the gap between frames in the tiling mode.int frame_normal_opacity = 100โ unfocused frame opacity in percent. Requires a running compositing manager to take actual effect ๐ซint frame_padding = 0โ the padding within a frame in the tiling mode, i.e. the space between the border of a frame and the windows within it.int frame_transparent_width = 0โ specifies the width of the remaining frame colored withframe_bg_active_colorifframe_bg_transparentis set.bool gapless_grid = trueโ this setting affects the size of the last client in a frame that's 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. No gap left behind ๐ธbool hide_covered_windows = falseโ if activated, windows are explicitly hidden when they're covered by another window in a frame with max layout. This only has a visible effect if a compositor is used. If activated, shadows do not stack up and transparent windows show the wallpaper behind them instead of the other clients in the max layout. Kind of a flex, ngl ๐ฆuint monitors_locked = 0โ if greater than 0, then the clients on all monitors aren't moved or resized anymore. If it's set to 0, then the arranging of monitors is enabled again, and all monitors are rearranged if their content has changed in the meantime.
โ ๏ธ Do not change this setting manually, bestie โ concurrency issues are lurking. Use the commandslockandunlockinstead, fr fr.
int mouse_recenter_gap = 0โ specifies the gap around a monitor. If the monitor is selected and the mouse position would be restored into this gap, it's set to the center of the monitor. Super useful when the monitor was left via mouse movement but gets reselected by keyboard: keyboard girlies stay winning โจ๏ธโจ If the gap is 0 (default), the mouse is never recentered.int pseudotile_center_threshold = 10โ if greater than 0, it specifies the least distance between a centered pseudotile window and the border of the frame or tile it's assigned to. If this distance is lower thanpseudotile_center_threshold, it's aligned to the top left of the client's tile. Snapping it into place, cute ๐bool raise_on_click = trueโ if set, a window is raised if it's clicked. The value of this setting is only noticed in floating mode.bool raise_on_focus = falseโ if set, a window is raised if it's focused. The value of this setting is only used in floating mode.bool raise_on_focus_temporarily = falseโ if set, a window is raised temporarily if it's focused on its tag. Temporarily in this case means that the window will return to its previous stacking position if another window is focused. Main character moment, then back in line ๐ShowFrameDecorations show_frame_decorations = focused_if_multipleโ this controls which frame decorations are shown at all. Options, bestie:noneshows no frame decorations at all,nonemptyshows decorations of frames that have client windows,if_multipleshows decorations on the tags with at least two frames,if_emptyshows decorations of frames that have no client windows,if_multiple_emptyshows decorations of frames that have no client windows on tags with at least two frames,focusedshows the decoration of focused and nonempty frames,focused_if_multipleshows decorations of focused and non-empty frames on tags with at least two frames.allshows all frame decorations.
SmartFrameSurroundings smart_frame_surroundings = offโ if set tohide_all, frame borders and gaps will be removed when there's no ambiguity regarding the focused frame. Set it tohide_gapsand only frame gaps get removed when there's no ambiguity regarding the focused frame. Turn off to always show frame borders and gaps.SmartWindowSurroundings smart_window_surroundings = offโ if set toone_window(oron), then window borders and gaps will be hidden in each frame that shows only one window. If set toone_window_and_frame, then only those frames are affected that are the only frame on their tag. Still, these hidden decorations can be configured by thetheme.minimalobject ๐ Turn off to always show window borders and gaps.int snap_distance = 10โ if a client is dragged in floating mode, then it snaps to neighbour clients if the distance between them is smaller thansnap_distance. Magnetic behavior, obsessed ๐งฒint snap_gap = 5โ specifies the remaining gap if a dragged client snaps to an edge in floating mode. Ifsnap_gapis set to 0, no gap will remain.bool swap_monitors_to_get_tag = trueโ if set: if you want to view a tag that's already 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.bool tabbed_max = trueโ if activated, multiple windows in a frame with the max layout algorithm are drawn as tabs. Tabs! We love a little folder moment ๐๏ธ- *
string tree_style = "*| +--."** โ 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-.
#-. child 0
| #-* child 00
| +-* child 01
+-. child 1
: #-* child 10
: +-* child 11
Useful values for tree_style are: โพโ โโโผโโ or -| |'--. or โพโ โโฐโผโโฎ. Aesthetic tree printer, we stan ๐
bool update_dragged_clients = falseโ 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 is released. Live preview vs. delayed reveal, pick your vibe ๐ฌbool verbose = falseโ if set, verbose output is logged to herbstluftwm'sstderr. The default value is controlled by the--verbosecommand line flag.color window_border_active_colorโ border color of a focused window.
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.active.color.
color window_border_inner_colorโ color of the inner border of a window.
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.inner_color.
int window_border_inner_widthโ the width of the inner border of a window. Must be less thanwindow_border_width, since it does not add to the window border width but is a part of it.
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.inner_width.
color window_border_normal_colorโ border color of an unfocused window.
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.normal.color.
color window_border_urgent_colorโ border color of an unfocused but urgent window. Urgent window said "notice me" ๐จ
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.urgent.color.
int window_border_widthโ border width of a window.
โ ๏ธ Warning: this only exists for compatibility reasons; it's only an alias for the attribute theme.border_width.
int window_gap = 0โ the gap between windows within one frame in the tiling mode.string wmname = herbstluftwmโ it controls the value of the_NET_WM_NAMEproperty 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_NAMEproperty on the root window is changed externally. Example usage, bestie:cycle_value wmname herbstluftwm LG3D
๐ท๏ธ tags
The tags (or virtual desktops or workspaces). This contains an entry index for each tag with the given index. Your whole workspace situation lives here โจ
uint countby-name: for attributes and children, seemonitors.by-namefocus: the object of the focused tag, equivalently, the tag on the focused monitor.bool at_end = false: all tags with this property activated will be kept at the end of the tag list. Usually, this property is set for special purpose tags like scratchpads. Little corner tags, love that ๐ซถint client_count: the number of clients on this tagint curframe_wcount: number of clients in the selected frameint curframe_windex: index of the focused client in the selected framebool floating = false: if the entire tag is set to floating modebool floating_focused = false: if the floating layer is focused (otherwise the tiling layer is)int frame_count: the number of frames on this taguint index = 0: index of this tag (the first index is 0)string name = name_: name of the tag (must be non-empty)
int urgent_countโ how many clients on this tag are currently screaming for attention (urgent, bestie, very main character of them).bool visible = falseโtrueif this tag is being shown on some monitor. That's it.focused_clientโ for its attributes and children, go look atclients.focus. โจtilingโ the frame tree situation, and honestly it's giving tree energy all the way down:focused_frameโ the currently focused frame (a leaf) inside this frame tree. For attributes and children, seetags.focus.tiling.root.rootcan be a frame leaf.LayoutAlgorithm algorithmint client_countRectangle content_geometryโ the geometry of the frame's contents, i.e. the area that actually gets filled by child frames or by client windows.string indexโ a string containing only0and1that describes where this frame sits in the tree. The empty string means the root frame. Append0(respectively1) to a frame index and you get the frame index of the first (respectively second) subtree. It's literally coordinates, but make it binary ๐int selection
rootcan be a frame split.Rectangle content_geometryโ the geometry of the frame's contents, i.e. of the area filled by child frames or client windows.decimal fractionstring indexโ a string containing only0and1that describes the position of the frame in the tree. The empty string denotes the root frame. Appending0(respectively1) to a frame index yields the frame index of the first (respectively second) subtree.int selectionSplitAlign split_type0can be a frame leaf. For attributes and children, seetags.focus.tiling.root.0can be a frame split. For attributes and children, seetags.focus.tiling.root.1can be a frame leaf. For attributes and children, seetags.focus.tiling.root.1can be a frame split. For attributes and children, seetags.focus.tiling.root.
๐ theme
First, the sacred geometry diagram. Study it. It's iconic:
inner_color/inner_width
โป outer_color/outer_width
โ โป
โ โ
โโโโโโดโโถโโโโโโโโโโโโโโโโโโทโโโโโโ โซ border_width
โ โ color โ โฌ + title_height + title_depth
โ โโโโทโโโโโโโโโโโโโโโโโโโโโโ โ โญ + padding_top
โ โ====================....โ โ
โ โ== window content ==....โ โ
โ โ====================..โพโโโโโโโโ background_color
โ โ........................โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโ โ โฑ border_width +
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โฐ padding_bottom
Setting an attribute of the theme object just propagates the value straight to the respective attribute of the tiling and the floating object. If the title area is divided into tabs, then the not selected tabs can be styled using the tab_... attributes. If these attributes are empty, then the colors are taken from the theme of the client that the tab refers to. ๐ฆ
color background_color = blackโ the color behind the window contents, visible when you resize. (Extremely "caught in 4k on resize" energy.)uint border_width = 0โ the base width of the border.color color = blackโ the basic background color of the border.color inner_color = blackโ color of the inner border.uint inner_width = 0โ width of the border around the client's content.CssFile::Ptr nameโ the absolute path to a css theme file. If this is empty, then the theme is specified by the attributes instead.color outer_color = blackโ color of the outer border.uint outer_width = 0โ width of a border close to the edge.uint padding_bottom = 0โ extra border width on the bottom.uint padding_left = 0โ extra border width on the left.uint padding_right = 0โ extra border width on the right.uint padding_top = 0โ extra border width on the top.string resetโ writing this resets all attributes to a default value. A little factory reset moment, as a treat ๐CssSource style_overrideโ additional css source to overwrite parts of the theme. All rules here have higher precedence than all rules in the theme. She said "my rules now" and honestly? slay.MaybeColor tab_color = Inheritโ if non-empty, the color of non-urgent and unfocused tabs.MaybeColor tab_outer_color = Inheritโ if non-empty, the outer border color of non-urgent and unfocused tabs; if empty, the colors are taken from the tab's client decoration settings.MaybeULong tab_outer_width = Inheritโ if non-empty, the outer border width of non-urgent and unfocused tabs.MaybeColor tab_title_color = Inheritโ if non-empty, the title color of non-urgent and unfocused tabs.bool tight_decoration = falseโ specifies whether the size hints also affect the window decoration or only the window contents of tiled clients (requires enabledsizehints_tiling). Read that condition again bestie, it's load-bearing.TextAlign title_align = leftโ the horizontal alignment of the title within the tab or title bar. The value is one of:left,center,right.color title_color = blackMaybeInt title_depth = 0โ the space below the baseline of the window title, or''for an automatic calculation based on the font.font title_font = fixedMaybeULong title_height = 0โ the space above the baseline of the window title, or''for an automatic calculation based on the font.TitleWhen title_when = alwaysโ when to show the window title:always,never, if the the client is in a tabbed scenario like a max frame (one_tab), if there aremultiple_tabsto be shown.
active โ configures the decoration of the focused client. ๐
color background_color = blackโ color behind window contents visible on resizeuint border_width = 0โ the base width of the bordercolor color = blackโ the basic background color of the bordercolor inner_color = blackโ color of the inner borderuint inner_width = 0โ width of the border around the clients contentcolor outer_color = blackโ color of the outer borderuint outer_width = 0โ width of an border close to the edgeuint padding_bottom = 0โ additional border width on the bottomuint padding_left = 0โ additional border width on the leftuint padding_right = 0โ additional border width on the rightuint padding_top = 0โ additional border width on the topstring resetโ writing this resets all attributes to a default valueMaybeColor tab_color = Inheritโ if non-empty, the color of non-urgent and unfocused tabsMaybeColor tab_outer_color = Inheritโ if non-empty, the outer border color of non-urgent and unfocused tabs; if empty, the colors are taken from the tab's client decoration settings.MaybeULong tab_outer_width = Inheritโ if non-empty, the outer border width of non-urgent and unfocused tabsMaybeColor tab_title_color = Inheritโ if non-empty, the title color of non-urgent and unfocused tabsbool tight_decoration = falseโ specifies whether the size hints also affect the window decoration or only the window contents of tiled clients (requires enabledsizehints_tiling)TextAlign title_align = leftโ the horizontal alignment of the title within the tab or title bar. The value is one of:left,center,rightcolor title_color = blackMaybeInt title_depth = 0โ the space below the baseline of the window title, or''for an automatic calculation based on the font.font title_font = fixedMaybeULong title_height = 0โ the space above the baseline of the window title, or''for an automatic calculation based on the font.TitleWhen title_when = alwaysโ when to show the window title:always,never, if the the client is in a tabbed scenario like a max frame (one_tab), if there aremultiple_tabsto be shown.
floating โ behaves analogously to tiling. Same deck of cards, different pile ๐
color background_color = blackโ color behind window contents visible on resizeuint border_width = 0โ the base width of the bordercolor color = blackโ the basic background color of the bordercolor inner_color = blackโ color of the inner borderuint inner_width = 0โ width of the border around the clients contentcolor outer_color = blackโ color of the outer borderuint outer_width = 0โ width of an border close to the edgeuint padding_bottom = 0โ additional border width on the bottomuint padding_left = 0โ additional border width on the leftuint padding_right = 0โ additional border width on the rightuint padding_top = 0โ additional border width on the topstring resetโ writing this resets all attributes to a default valueMaybeColor tab_color = Inheritโ if non-empty, the color of non-urgent and unfocused tabsMaybeColor tab_outer_color = Inheritโ if non-empty, the outer border color of non-urgent and unfocused tabs; if empty, the colors are taken from the tab's client decoration settings.MaybeULong tab_outer_width = Inheritโ if non-empty, the outer border width of non-urgent and unfocused tabsMaybeColor tab_title_color = Inheritโ if non-empty, the title color of non-urgent and unfocused tabsbool tight_decoration = falseโ specifies whether the size hints also affect the window decoration or only the window contents of tiled clients (requires enabledsizehints_tiling)TextAlign title_align = leftโ the horizontal alignment of the title within the tab or title bar. The value is one of:left,center,rightcolor title_color = blackMaybeInt title_depth = 0โ the space below the baseline of the window title, or''for an automatic calculation based on the font.- **
font title_font = fixed MaybeULong title_height = 0โ literally the space above the baseline of the window title, or''if you want it auto-calculated from the font ๐TitleWhen title_when = alwaysโ controls when the window title even shows up:always,never, if the the client is in a tabbed scenario like a max frame (one_tab), or if there aremultiple_tabsto be shown. pick your fighter ๐activeโ decorates the focused client. For attributes and children, seetheme.activeโจnormalโ the default decoration scheme for clients. For attributes and children, seetheme.active๐ซถurgentโ decorates urgent clients (yes, the ones screaming for attention ๐ญ). For attributes and children, seetheme.activefullscreenโ configures clients in fullscreen state. For attributes and children, seetheme.floating๐minimalโ configures clients with minimal decorations, triggered bysmart_window_surroundings. For attributes and children, seetheme.floating๐งnormalโ the default decoration scheme for clients. For attributes and children, seetheme.activetilingโ decorates tiled clients; setting one of its attributes propagates the respective attribute of theactive,normalandurgentchild objects. For attributes and children, seetheme.floating๐ฆurgentโ configures the decoration of urgent clients. For attributes and children, seetheme.active
โจ types โจ
This lists the types that are used for attributes and command arguments. think of it as the personality types of every value you'll ever pass ๐
boolโ Type representing boolean values, i.e. an on or off state, with aliasestrueandfalse. When writing to a boolean value, one can also specifytogglein order to alter its value. so chaotic, so convenient ๐string fullnameโ the full and unique name of this typestring shortnameโ A short (one-character long) name of this type which is used in the output of theattrcommand
colorโ Type representing colors. A color can be defined in one of the following formats:#RRGGBBwhere R, G, B are hexidecimal digits (0-9,A-F), andRR,GG,BBrepresent the values for red, green, blue. ๐#RRGGBBAArepresents a color with alpha-valueAA. The alpha value00is fully transparent andFFis fully opaque/intransparent. (so00is the invisible-girl era andFFis main character energy ๐)- a common color name like
red,blue,orange, etc. For attributes and children, seetypes.bool
decimalโ Fixed precision decimal numbers, e.g.0.34. For attributes and children, seetypes.boolfontโ A font specification (font family with modifiers regarding size, weight, etc.) in one of the following formats:- Fontconfig description. This supports antialiased fonts, for example:
Dejavu Sans:pixelsize=12Bitstream Vera Sans:size=12:bold
- X logical font description (XLFD), as provided by the
xfontseltool. No antialiasing is supported here, but this is usually superior for bitmap fonts. For example:-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*for a standard bitmap font available on most systems. For attributes and children, seetypes.bool
- Fontconfig description. This supports antialiased fonts, for example:
intโ Type representing signed integers. When overwriting an integer, you can increase or decrease its value relatively by writing+=Nor-=NwhereNis an integer. So for example, writing+=3to an attribute increases its value by 3. For attributes and children, seetypes.boolโจnamesโ A fixed set of names, depending on the context, e.g. names of layout algorithms or the split type of a non-leaf frame (which is onlyhorizontalorvertical). For attributes and children, seetypes.boolrectangleโ A rectangle on the screen consisting of a size and the position on the screen. The format isWxH+X+YwhereWis the width,His the height, andXandYare the coordinates of the top left corner of the rectangle:Xis the number of pixels to the left screen edge andYis the number of pixels to the top screen edge. (ifXorYis negative, then the+turns into-). For example:800x600+800+0or400x200-10+30. For attributes and children, seetypes.bool๐regexโ A POSIX extended regular expression. Note that when passing a regex on the command line, additional quoting can be necessary. For explanations and examples, see section 9.4.6 of the documentation:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04_06. For attributes and children, seetypes.bool(ngl regex still scares me and I'm not sorry ๐ญ)stringโ Type representing normal text. For attributes and children, seetypes.booluintโ Type representing unsigned (i.e. non-negative) integers. When overwriting an integer, you can increase or decrease its value relatively by writing+=Nor-=NwhereNis an integer. For attributes and children, seetypes.boolwindowidโ The window id is the number of a window. This can be a managed window (i.e. client) or an unmanaged window (e.g. a panel, a menu, or a desktop window). The default format is0xHEXwhereHEXis a hexadecimal number (digits0-9anda-f) but it can also be specified in the decimal system (base 10), or as an octal number (with prefix0and base 8). When a window id is printed, it is always printed in the0xHEXformat and without any leading zeroes. For attributes and children, seetypes.bool๐
๐ watchers ๐
uint countโ the number of attributes that are watched
๐ธ AUTOSTART FILE ๐ธ
okay so there's no config file โ there's an autostart file, and it's executed on startup. It's also executed on the reload command. If not specified by the --autostart argument, the autostart file lives 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. bestie the fallback is literally the safety net ๐ซถ
For a quick install, copy the default autostart file to ~/.config/herbstluftwm/. one command, whole setup, slay โจ
๐ 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:
attribute_changed PATH OLDVALUE NEWVALUEโ The attributePATHwas changed fromOLDVALUEtoNEWVALUE. Requires that the attributePATHhas been passed to thewatchcommand before. no watch, no tea ๐ตfullscreen [on|off] WINIDโ The fullscreen state of windowWINIDwas changed to[on|off].tag_changed TAG MONITORโ The tagTAGwas selected onMONITOR.focus_changed WINID TITLEโ The windowWINIDwas focused. Its window title isTITLE.window_title_changed WINID TITLEโ The title of the focused window was changed. Its window id isWINIDand its new title isTITLE.tag_flagsโ The flags (i.e. urgent or filled state) have been changed.tag_added TAGโ A tag namedTAGwas added.tag_removed TAGโ The tag namedTAGwas removed.tag_renamed OLD NEWโ The tag name changed fromOLDtoNEW.urgent [on|off] WINIDโ The urgent state of client with givenWINIDhas been changed to[on|off].rule NAME WINIDโ A window with the idWINIDappeared which triggered a rule with the consequencehook=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 defaultpanel.shquits on this hook. Many scripts are using this hook. bye bestie ๐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. put it first, fr fr โญ
๐ THEMES/STYLESHEETS ๐
The look of client decorations can be controlled via the attributes under the theme. object, or in a more granular way via stylesheets, inspired by CSS. we love a glow-up ๐
More documentation on the theme format will come soon. (manifesting โจ)
๐ 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_temporarilyis 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. it's giving layered cake, and you're the main character on top ๐
๐ฆ EWMH AND X11 PROPERTIES ๐ฆ
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_preventionis disabled.
Moreover, herbstluftwm sets the X11 properties HLWM_FLOATING_WINDOW and HLWM_TILING_WINDOW to indicate whether a window is in floating or tiling mode, that is, the value of the client's floating_effectively attribute. icon behavior, honestly โจ
โญ ENVIRONMENT VARIABLES โญ
DISPLAYโ Specifies theDISPLAYto use.
๐ FILES ๐
The following files are used by herbstluftwm:
autostart, see section AUTOSTART FILE.
๐ EXIT STATUS ๐
Returns 0 on success. Returns EXIT_FAILURE if it cannot startup or if wmexec fails. that's it, that's the whole mood ๐
๐ BUGS ๐
See the herbstluftwm Github issues: https://github.com/herbstluftwm/herbstluftwm/issues. every icon has haters, report them there ๐
๐ซถ COMMUNITY ๐ซถ
Feel free to join the IRC channel #herbstluftwm on irc.libera.chat. come hang out, we don't bite ๐ธ
๐ AUTHOR ๐
herbstluftwm was written by Thorsten Wiรmann. All contributors are listed in the herbstluftwm distribution AUTHORS file. legends only, no cap
๐ RESOURCES ๐
Homepage: http://herbstluftwm.org
Github page: http://github.com/herbstluftwm/herbstluftwm
Patch submission and bug reporting:
hlwm@lists.herbstluftwm.org
๐ COPYING ๐
Copyright 2011-2020 Thorsten Wiรmann. All rights reserved.
This software is licensed under the "Simplified BSD License". See LICENSE for details.
that's the whole page bestie, you made it to the end ๐ this was herbstluftwm version 0.9.6, dated 2026-04-03 โ go forth and tile your little heart out, ily, periodt ๐โจ
๐ฆ where this page comes from
- arch rolling: herbstluftwm 0.9.6-1 ยท BSD-2-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms