BSPWM(1)
π BSPWM β bestie's guide to the binary space partitioning window manager π
okay so this is the manual for bspwm, and if you're here it's because you want windows to behave. good news: I got you. this is the whole thing, all three parts, no skips, no "lol just read the source". let's go π«Ά
β¨ NAME β¨
bspwm β Binary space partitioning window manager. that's it, that's the name, and honestly? iconic.
β¨ SYNOPSIS β¨
bspwm [-h|-v|-c CONFIG_PATH]
bspc --print-socket-path
bspc DOMAIN [SELECTOR] COMMANDS
bspc COMMAND [OPTIONS] [ARGUMENTS]
β¨ DESCRIPTION β¨
okay so bspwm is a tiling window manager that represents windows as the leaves of a full binary tree. like, every window is a leaf, every split is a branch, and the whole thing is a tree. it's giving geometry homework but make it aesthetic π³
and here's the thing: it doesn't have a big config file where you set everything at boot. no no. it is controlled and configured via bspc. you talk to it at runtime. main character energy fr fr.
β¨ OPTIONS β¨
-hβ prints the synopsis and then peaces out. bye bestie π-vβ prints the version and exits. for when you need to know what you're running.-c CONFIG_PATHβ use the given configuration file. yes, you can point it at a specific one.--print-socket-pathβ prints thebspwmsocket path and exits. useful for scripting iykyk π¦
β¨ COMMON DEFINITIONS β¨
these little guys show up all over the place, so learn them once:
DIR := north | west | south | east
CYCLE_DIR := next | prev
β¨ SELECTORS β¨
okay so selectors are how you point at a target node, desktop, or monitor. and the vibe is: you can either describe the thing relatively ("the one next to the focused one") or just name it globally ("the one literally called this").
here's the shape of them β an optional reference, a descriptor, and then however many non-conflicting modifiers you want:
[REFERENCE#]DESCRIPTOR(.MODIFIER)*
so the relative targets get computed in relation to the given reference. and the default reference value? focused. obviously. it's always the focused one unless you say otherwise π
oh and here's a cute trick: you can prepend an exclamation mark to any modifier to reverse its meaning. [!]leaf means "not a leaf". flipped. reversed. slay.
β οΈ heads up bestie: these characters cannot be used in monitor or desktop names:#,:,.
and if a monitor or desktop has a name that's, like, invalid (because it contains one of those characters), there's a special selector for that: %<name>. that's the escape hatch. π
πΈ Node
select a node. here's the whole grammar:
NODE_SEL := [NODE_SEL#](DIR|CYCLE_DIR|PATH|any|first_ancestor|last|newest|
older|newer|focused|pointed|biggest|smallest|
<node_id>)[.[!]focused][.[!]active][.[!]automatic][.[!]local]
[.[!]leaf][.[!]window][.[!]STATE][.[!]FLAG][.[!]LAYER][.[!]SPLIT_TYPE]
[.[!]same_class][.[!]descendant_of][.[!]ancestor_of]
STATE := tiled|pseudo_tiled|floating|fullscreen
FLAG := hidden|sticky|private|locked|marked|urgent
LAYER := below|normal|above
SPLIT_TYPE := horizontal|vertical
PATH := @[DESKTOP_SEL:][[/]JUMP](/JUMP)*
JUMP := first|1|second|2|brother|parent|DIR
π§ Descriptors
DIRβ selects the window in the given (spacial) direction relative to the reference node.CYCLE_DIRβ selects the node in the given (cyclic) direction relative to the reference node, within a depth-first in-order traversal of the tree. (yes, that's a mouthful. it walks the tree in order and steps next/prev. π)PATHβ selects the node at the given path.anyβ selects the first node that matches the given selectors.first_ancestorβ selects the first ancestor of the reference node that matches the given selectors.lastβ selects the previously focused node relative to the reference node.newestβ selects the newest node in the history of the focused node.olderβ selects the node older than the reference node in the history.newerβ selects the node newer than the reference node in the history.focusedβ selects the currently focused node. the moment. the it-girl.pointedβ selects the leaf under the pointer. π±οΈbiggestβ selects the biggest leaf.smallestβ selects the smallest leaf. tiny. baby. π<node_id>β selects the node with the given ID.
π§ Path Jumps
so the initial node is the focused node β or the root, if the path starts with / β of the reference desktop. or of the selected desktop, if the path has a DESKTOP_SEL prefix. and then you jump:
1|firstβ jumps to the first child.2|secondβ jumps to the second child.brotherβ jumps to the brother node.parentβ jumps to the parent node.DIRβ jumps to the node holding the edge in the given direction.
π§ Modifiers
[!]focusedβ only consider the focused node.[!]activeβ only consider nodes that are the focused node of their desktop.[!]automaticβ only consider nodes in automatic insertion mode. see also--presel-dirunder Node in the DOMAINS section below. π[!]localβ only consider nodes in the reference desktop.[!]leafβ only consider leaf nodes.[!]windowβ only consider nodes that hold a window.[!](tiled|pseudo_tiled|floating|fullscreen)β only consider windows in the given state.[!]same_classβ only consider windows that have the same class as the reference window.[!]descendant_ofβ only consider nodes that are descendants of the reference node.[!]ancestor_ofβ only consider nodes that are ancestors of the reference node.[!](hidden|sticky|private|locked|marked|urgent)β only consider windows that have the given flag set.[!](below|normal|above)β only consider windows in the given layer.[!](horizontal|vertical)β only consider nodes with the given split type.
πΈ Desktop
select a desktop. grammar time:
DESKTOP_SEL := [DESKTOP_SEL#](CYCLE_DIR|any|last|newest|older|newer|
[MONITOR_SEL:](focused|^<n>)|
<desktop_id>|<desktop_name>)[.[!]focused][.[!]active]
[.[!]occupied][.[!]urgent][.[!]local]
[.[!]LAYOUT][.[!]user_LAYOUT]
LAYOUT := tiled|monocle
π§ Descriptors
CYCLE_DIRβ selects the desktop in the given direction relative to the reference desktop.anyβ selects the first desktop that matches the given selectors.lastβ selects the previously focused desktop relative to the reference desktop.newestβ selects the newest desktop in the history of the focused desktops.olderβ selects the desktop older than the reference desktop in the history.newerβ selects the desktop newer than the reference desktop in the history.focusedβ selects the currently focused desktop.^<n>β selects the *n*th desktop. and ifMONITOR_SELis given, it selects the *n*th desktop on the selected monitor. β¨<desktop_id>β selects the desktop with the given ID.<desktop_name>β selects the desktop with the given name.
π§ Modifiers
[!]focusedβ only consider the focused desktop.[!]activeβ only consider desktops that are the focused desktop of their monitor.[!]occupiedβ only consider occupied desktops.[!]urgentβ only consider urgent desktops.[!]localβ only consider desktops inside the reference monitor.[!](tiled|monocle)β only consider desktops with the given layout.[!](user_tiled|user_monocle)β only consider desktops which have the given layout asuserLayout.
πΈ Monitor
select a monitor. last one, you got this:
MONITOR_SEL := [MONITOR_SEL#](DIR|CYCLE_DIR|any|last|newest|older|newer|
focused|pointed|primary|^<n>|
<monitor_id>|<monitor_name>)[.[!]focused][.[!]occupied]
π§ Descriptors
DIRβ selects the monitor in the given (spacial) direction relative to the reference monitor.CYCLE_DIRβ selects the monitor in the given (cyclic) direction relative to the reference monitor.anyβ selects the first monitor that matches the given selectors.lastβ selects the previously focused monitor relative to the reference monitor.newestβ selects the newest monitor in the history of the focused monitors.olderβ selects the monitor older than the reference monitor in the history.newerβ selects the monitor newer than the reference monitor in the history.focusedβ selects the currently focused monitor.pointedβ selects the monitor under the pointer. π±οΈβ¨primaryβ selects the primary monitor.^<n>β selects the *n*th monitor.<monitor_id>β selects the monitor with the given ID.<monitor_name>β selects the monitor with the given name.
π§ Modifiers
[!]focusedβ only consider the focused monitor.[!]occupiedβ only consider monitors where the focused desktop is occupied.
β¨ WINDOW STATES β¨
four states, all with main character energy, each one a different personality:
tiledβ its size and position are determined by the window tree. the classic. the default vibe.pseudo_tiledβ a tiled window that automatically shrinks but doesn't stretch beyond its floating size. it can get smaller but it will NOT get bigger. boundaries. πfloatingβ can be moved/resized freely. and even though it doesn't use any tiling space, it is still part of the window tree. it's not leaving the family, it's just doing its own thing.fullscreenβ fills its monitor rectangle and has no borders. zero borders. nothing. just window. π
β¨ NODE FLAGS β¨
little booleans with big feelings:
hiddenβ is hidden and doesn't occupy any tiling space. gone but not gone. π«₯stickyβ stays in the focused desktop of its monitor.privateβ tries to keep the same tiling position/size.lockedβ ignores the node--closemessage. you literally cannot tell it to close. it said no. π«markedβ is marked (useful for deferred actions). and here's the detail bestie: a marked node becomes unmarked after being sent on a preselected node. one and done.urgentβ has its urgency hint set. and this flag is set externally β bspwm doesn't set it, something else does. π
β¨ STACKING LAYERS β¨
there's three stacking layers: BELOW, NORMAL and ABOVE.
and within each layer, the windows are ordered like this:
tiled & pseudo-tiled < floating < fullscreen
so tiled and pseudo-tiled sit at the bottom of the layer, floating goes above them, fullscreen goes above everything. the hierarchy. the pecking order. π
β¨ RECEPTACLES β¨
okay this one's so clever. a leaf node that doesn't hold any window is called a receptacle. it's like an empty seat at the table, waiting.
when a node is inserted on a receptacle in automatic mode, it will replace the receptacle. so the empty spot just... becomes the thing. π¦
and a receptacle can be:
- inserted on a node
- preselected
- killed
so the play here is: you can build a whole tree whose leaves are all receptacles. and then, using the appropriate rules, you send windows onto the leaves of that tree. and boom β you've stored a layout and can recreate it later.
this feature is used in examples/receptacles to store and recreate layouts. β¨
part 2 coming, don't go anywhere bestie π
π DOMAINS π
okay so bspc is organised into these little groups called domains, and every one of them has its own general syntax β think of them as group chats you can slide into to talk about a specific thing π¬. Here's the whole roster, bestie:
π Node π
β¨ General Syntax β¨
node [NODE_SEL] COMMANDS
If NODE_SEL is omitted, focused is assumed. no thoughts, just vibes, it already knows who you mean π
π Commands π
-f,--focus[NODE_SEL]β Focus the selected or given node. give it the spotlight, it's their moment β-a,--activate[NODE_SEL]β Activate the selected or given node.-d,--to-desktopDESKTOP_SEL[--follow]β Send the selected node to the given desktop. If--followis passed, the focused node will stay focused. π¦-m,--to-monitorMONITOR_SEL[--follow]β Send the selected node to the given monitor. If--followis passed, the focused node will stay focused.-n,--to-nodeNODE_SEL[--follow]β Send the selected node on the given node. If--followis passed, the focused node will stay focused.-s,--swapNODE_SEL[--follow]β Swap the selected node with the given node. If--followis passed, the focused node will stay focused. it's giving trading places β¨-p,--presel-dir[~]DIR|cancelβ Preselect the splitting area of the selected node (or cancel the preselection). If~is prepended toDIRand the current preselection direction matchesDIR, then the argument is interpreted ascancel. A node with a preselected area is said to be in "manual insertion mode". π«Ά-o,--presel-ratioRATIOβ Set the splitting ratio of the preselection area.-v,--movedxdyβ Move the selected window bydxpixels horizontally anddypixels vertically.-z,--resizetop|left|bottom|right|top_left|top_right|bottom_right|bottom_leftdxdyβ Resize the selected window by moving the given handle bydxpixels horizontally anddypixels vertically. drag it like it owes you money π-y,--typeCYCLE_DIR|horizontal|verticalβ Set or cycle the splitting type of the selected node.-r,--ratioRATIO|(+|-)(PIXELS|FRACTION)β Set the splitting ratio of the selected node (0 < RATIO < 1).-R,--rotate90|270|180β Rotate the tree rooted at the selected node. spin it, queen π₯-F,--fliphorizontal|verticalβ Flip the tree rooted at selected node.-E,--equalizeβ Reset the split ratios of the tree rooted at the selected node to their default value.-B,--balanceβ Adjust the split ratios of the tree rooted at the selected node so that all windows occupy the same area. equal rights, equal screen real estate π-C,--circulateforward|backwardβ Circulate the windows of the tree rooted at the selected node.-t,--state~|[~]STATEβ Set the state of the selected window. If~is present and the current state matchesSTATE, then the argument is interpreted as its last state. If the argument is just~withSTATEomitted, then the state of the selected window is set to its last state. π§-g,--flaghidden|sticky|private|locked|marked[=on|off]β Set or toggle the given flag for the selected node.-l,--layerbelow|normal|aboveβ Set the stacking layer of the selected window.-i,--insert-receptacleβ Insert a receptacle node at the selected node.-c,--closeβ Close the windows rooted at the selected node. gentle exit, bye bestie π-k,--killβ Kill the windows rooted at the selected node. okay this one is the unhinged version, no cap π
π¦ Desktop π¦
β¨ General Syntax β¨
desktop [DESKTOP_SEL] COMMANDS
If DESKTOP_SEL is omitted, focused is assumed. again, it already knows π
π COMMANDS π
-f,--focus[DESKTOP_SEL]β Focus the selected or given desktop.-a,--activate[DESKTOP_SEL]β Activate the selected or given desktop.-m,--to-monitorMONITOR_SEL[--follow]β Send the selected desktop to the given monitor. If--followis passed, the focused desktop will stay focused.-s,--swapDESKTOP_SEL[--follow]β Swap the selected desktop with the given desktop. If--followis passed, the focused desktop will stay focused.-l,--layoutCYCLE_DIR|monocle|tiledβ Set or cycle the layout of the selected desktop. monocle is for when you want ONE thing and one thing only, main character energy fr π-n,--rename<new_name>β Rename the selected desktop. glow-up, name edition β¨-b,--bubbleCYCLE_DIRβ Bubble the selected desktop in the given direction.-r,--removeβ Remove the selected desktop. we don't talk about them anymore π
πΈ Monitor πΈ
β¨ General Syntax β¨
monitor [MONITOR_SEL] COMMANDS
If MONITOR_SEL is omitted, focused is assumed.
π Commands π
-f,--focus[MONITOR_SEL]β Focus the selected or given monitor.-s,--swapMONITOR_SELβ Swap the selected monitor with the given monitor.-a,--add-desktops<name>...β Create desktops with the given names in the selected monitor.-o,--reorder-desktops<name>...β Reorder the desktops of the selected monitor to match the given order.-d,--reset-desktops<name>...β Rename, add or remove desktops depending on whether the number of given names is equal, superior or inferior to the number of existing desktops. lowkey does whatever the math says, it's flexible like that π«Ά-g,--rectangleWxH+X+Yβ Set the rectangle of the selected monitor.-n,--rename<new_name>β Rename the selected monitor.-r,--removeβ Remove the selected monitor.
π Query π
β¨ General Syntax β¨
query COMMANDS [OPTIONS]
π Commands π
The optional selectors are references. iykyk β you're peeking, not poking π
-N,--nodes[NODE_SEL]β List the IDs of the matching nodes.-D,--desktops[DESKTOP_SEL]β List the IDs (or names) of the matching desktops.-M,--monitors[MONITOR_SEL]β List the IDs (or names) of the matching monitors.-T,--treeβ Print a JSON representation of the matching item. data bestie behaviour π
π Options π
-m,--monitor[MONITOR_SEL|MONITOR_MODIFIERS],-d,--desktop[DESKTOP_SEL|DESKTOP_MODIFIERS],-n,--node[NODE_SEL|NODE_MODIFIERS]β Constrain matches to the selected monitors, desktops or nodes. yes they're all bundled into one lil bullet, that's just how it is β¨--namesβ Print names instead of IDs. Can only be used with-Mand-D. > note this one has a buddy system, it will NOT work alone π«
π Wm π
β¨ General Syntax β¨
wm COMMANDS
π Commands π
-d,--dump-stateβ Dump the current world state on standard output. spilling ALL the tea, to stdout π΅-l,--load-state<file_path>β Load a world state from the given file. The path must be absolute. > no relative paths here bestie, absolute or nothing π-a,--add-monitor<name> WxH+X+Yβ Add a monitor for the given name and rectangle.-O,--reorder-monitors<name>...β Reorder the list of monitors to match the given order.-o,--adopt-orphansβ Manage all the unmanaged windows remaining from a previous session. aww, adopting the strays π₯Ί-h,--record-historyon|offβ Enable or disable the recording of node focus history.-g,--get-statusβ Print the current status information.-r,--restartβ Restart the window manager. brb rebooting β¨
π Rule π
β¨ General Syntax β¨
rule COMMANDS
π Commands π
-a,--add(<class_name>|*)[:(<instance_name>|*)[:(<name>|*)]][-o|--one-shot][monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL][state=STATE][layer=LAYER][honor_size_hints=(true|false|tiled|floating)][split_dir=DIR][split_ratio=RATIO][(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)][rectangle=WxH+X+Y]β Create a new rule. Colons in theinstance_name,class_name, ornamefields can be escaped with a backslash. that's a LOT of knobs and honestly? slay ποΈ-r,--remove^<n>|head|tail|(<class_name>|*)[:(<instance_name>|*)[:(<name>|*)]]...β Remove the given rules.-l,--listβ List the rules.
ποΈ Config ποΈ
β¨ General Syntax β¨
config [-m MONITOR_SEL|-d DESKTOP_SEL|-n NODE_SEL] <setting> [<value>]
Get or set the value of <setting>. peek it or tweak it, your call π«Ά
π‘ Subscribe π‘
β¨ General Syntax β¨
subscribe [OPTIONS] (all|report|monitor|desktop|node|...)*
Continuously print events. See the EVENTS section for the description of each event. it just keeps going and going and going, obsessed π
π Options π
-f,--fifoβ Print a path to a FIFO from which events can be read and return.-c,--countCOUNTβ Stop the correspondingbspcprocess after having receivedCOUNTevents.
πͺ Quit πͺ
β¨ General Syntax β¨
quit [<status>]
Quit with an optional exit status. leaving the group chat, but with β¨optionsβ¨
π EXIT CODES π
If the server can't handle a message, bspc will return with a non-zero exit code.
translation: if something goes sideways, you'll get a non-zero code back. that's your sign something's off, bestie π©
β¨ SETTINGS β¨
Colors are written like #RRGGBB (hex, bestie, no escaping it). Booleans are true, on, false or off. And listen β every single boolean setting defaults to false unless the page says otherwise. Every. Single. One. π
πΈ Global Settings πΈ
normal_border_colorβ the border color of a window that is not focused.active_border_colorβ the border color of a focused window that lives on an unfocused monitor. Yes, that's a whole separate vibe.focused_border_colorβ the border color of a focused window on a focused monitor. The main character window, fr fr.presel_feedback_colorβ the color of thenode --presel-{dir,ratio}message feedback area.split_ratioβ the default split ratio.status_prefixβ a prefix that gets prepended to each of the status lines.external_rules_commandβ the absolute path to the command used to retrieve rule consequences. That command gets handed these arguments: the window ID, the class name, the instance name, and the intermediate consequences. And its output must be formatted like this:key1=value1 key2=value2 ...β the valid key/value pairs are the ones listed in the description of therulecommand. iykyk πautomatic_schemeβ the insertion scheme used when the insertion point is in automatic mode. Accepts:longest_side,alternate,spiral.initial_polarityβ which child a new window gets attached to when you add a window on a single window tree in automatic mode. Accepts:first_child,second_child.directional_focus_tightnessβ how tight the algorithm is that decides whether a window is on the DIR side of another window. Accepts:high,low.removal_adjustmentβ adjust the brother when unlinking a node from the tree, in accordance with the automatic insertion scheme.presel_feedbackβ draw the preselection feedback area. Defaults totrueβ¨borderless_monocleβ strip the borders off tiled windows for the monocle desktop layout.gapless_monocleβ strip the gaps off tiled windows for the monocle desktop layout.top_monocle_padding,right_monocle_padding,bottom_monocle_padding,left_monocle_paddingβ padding space added at the sides of the screen for the monocle desktop layout.single_monocleβ set the desktop layout to monocle when there's only one tiled window in the tree.borderless_singletonβ remove the borders of the only window on the only monitor, no matter what its layout is. Periodt.pointer_motion_intervalβ the minimum interval, in milliseconds, between two motion notify events.pointer_modifierβ the keyboard modifier used for moving or resizing windows. Accepts:shift,control,lock,mod1,mod2,mod3,mod4,mod5.pointer_action1,pointer_action2,pointer_action3β the action performed when you presspointer_modifier+button<n>. Accepts:move,resize_side,resize_corner,focus,none.click_to_focusβ the button used for focusing a window (or a monitor). Possible values:button1,button2,button3,any,none. Defaults tobutton1π«Άswallow_first_clickβ don't replay the click that makes a window focused, ifclick_to_focusisn'tnone.focus_follows_pointerβ focus the window that's under the pointer.pointer_follows_focusβ when you focus a window, put the pointer at its center.pointer_follows_monitorβ when you focus a monitor, put the pointer at its center.mapping_events_countβ handle the nextmapping_events_countmapping notify events. A negative value implies that every event needs to be handled.ignore_ewmh_focusβ ignore EWMH focus requests coming from applications.ignore_ewmh_fullscreenβ block the fullscreen state transitions that originate from an EWMH request. Possible values:none,all, or a comma separated list of:enter,exit.ignore_ewmh_strutsβ ignore strut hinting from clients requesting to reserve space (i.e. task bars).center_pseudo_tiledβ center pseudo tiled windows into their tiling rectangles. Defaults totrueπremove_disabled_monitorsβ consider disabled monitors as disconnected.remove_unplugged_monitorsβ remove unplugged monitors.merge_overlapping_monitorsβ merge overlapping monitors (the bigger one remains). Sorry to the smaller one π
π₯οΈ Monitor and Desktop Settings π₯οΈ
top_padding,right_padding,bottom_padding,left_paddingβ padding space added at the sides of the monitor or desktop.
π Desktop Settings π
window_gapβ the size of the gap that separates windows. The breathing room. The ~aura~.
π¦ Node Settings π¦
border_widthβ window border width.honor_size_hintsβ iftrue, apply ICCCM window size hints to all windows. Iffloating, only apply them to floating and pseudo tiled windows. Iftiled, only apply them to tiled windows. Iffalse, don't apply them at all. Defaults tofalse.
π±οΈ POINTER BINDINGS π±οΈ
click_to_focusβ focus the window (or the monitor) under the pointer, as long as the value isn'tnone.pointer_modifier+button1β move the window under the pointer.pointer_modifier+button2β resize the window under the pointer by dragging the nearest side.pointer_modifier+button3β resize the window under the pointer by dragging the nearest corner.
The behavior of pointer_modifier + button<n> can be modified through the pointer_action<n> setting. Slay. π
π£ EVENTS π£
reportβ see the next section for the description of the format. (Spoiler: it's the very next heading, bestie.)monitor_add <monitor_id> <monitor_name> <monitor_geometry>β a monitor is added.monitor_rename <monitor_id> <old_name> <new_name>β a monitor is renamed.monitor_remove <monitor_id>β a monitor is removed. bye bestie πmonitor_swap <src_monitor_id> <dst_monitor_id>β a monitor is swapped.monitor_focus <monitor_id>β a monitor is focused.monitor_geometry <monitor_id> <monitor_geometry>β the geometry of a monitor changed.desktop_add <monitor_id> <desktop_id> <desktop_name>β a desktop is added.desktop_rename <monitor_id> <desktop_id> <old_name> <new_name>β a desktop is renamed.desktop_remove <monitor_id> <desktop_id>β a desktop is removed.desktop_swap <src_monitor_id> <src_desktop_id> <dst_monitor_id> <dst_desktop_id>β a desktop is swapped.desktop_transfer <src_monitor_id> <src_desktop_id> <dst_monitor_id>β a desktop is transferred.desktop_focus <monitor_id> <desktop_id>β a desktop is focused.desktop_activate <monitor_id> <desktop_id>β a desktop is activated.desktop_layout <monitor_id> <desktop_id> tiled|monocleβ the layout of a desktop changed.node_add <monitor_id> <desktop_id> <ip_id> <node_id>β a node is added.node_remove <monitor_id> <desktop_id> <node_id>β a node is removed.node_swap <src_monitor_id> <src_desktop_id> <src_node_id> <dst_monitor_id> <dst_desktop_id> <dst_node_id>β a node is swapped.node_transfer <src_monitor_id> <src_desktop_id> <src_node_id> <dst_monitor_id> <dst_desktop_id> <dst_node_id>β a node is transferred.node_focus <monitor_id> <desktop_id> <node_id>β a node is focused.node_activate <monitor_id> <desktop_id> <node_id>β a node is activated.node_presel <monitor_id> <desktop_id> <node_id> (dir DIR|ratio RATIO|cancel)β a node is preselected.node_stack <node_id_1> below|above <node_id_2>β a node is stacked below or above another node.node_geometry <monitor_id> <desktop_id> <node_id> <node_geometry>β the geometry of a window changed.node_state <monitor_id> <desktop_id> <node_id> tiled|pseudo_tiled|floating|fullscreen on|offβ the state of a window changed.node_flag <monitor_id> <desktop_id> <node_id> hidden|sticky|private|locked|marked|urgent on|offβ one of the flags of a node changed.node_layer <monitor_id> <desktop_id> <node_id> below|normal|aboveβ the layer of a window changed.pointer_action <monitor_id> <desktop_id> <node_id> move|resize_corner|resize_side begin|endβ a pointer action occurred.
β οΈ Heads up bestie: bspwm initializes monitors before it reads messages on its socket, therefore the initial monitor events can't be received. It's not you, it's the startup order. π
π REPORT FORMAT π
Each report event message is composed of items separated by colons.
Each item has the form <type><value> where <type> is the first character of the item. Sneaky little prefix energy. π
M<monitor_name>β focused monitor.m<monitor_name>β unfocused monitor.O<desktop_name>β occupied focused desktop.o<desktop_name>β occupied unfocused desktop.F<desktop_name>β free focused desktop.f<desktop_name>β free unfocused desktop.U<desktop_name>β urgent focused desktop.u<desktop_name>β urgent unfocused desktop.L(T|M)β layout of the focused desktop of a monitor.T(T|P|F|=|@)β state of the focused node of a focused desktop.G(S?P?L?M?)β active flags of the focused node of a focused desktop.
π± ENVIRONMENT VARIABLES π±
BSPWM_SOCKETβ the path of the socket used for the communication betweenbspcandbspwm. If it isn't defined, then this path gets used instead:/tmp/bspwm<host_name>_<display_number>_<screen_number>-socket.
π CONTRIBUTORS π
- Steven Allen
<steven at stebalien.com> - Thomas Adam
<thomas at xteddy.org> - Ivan Kanakarakis
<ivan.kanak at gmail.com>
π AUTHOR π
Bastien Dejean <nihilhill at gmail.com>
And that's the whole page, bestie β every flag, every event, every color code, no skips, no cap. π«Ά This was Bspwm 0.9.12 (the version, iconic) and the page is dated 10/08/2025, so go forth and tile your windows with main character energy. slay, periodt, bye π
β¨π
π¦ where this page comes from
- alpine 3.24: bspwm-doc 0.9.12-r0 Β· BSD-2-Clause
- arch rolling: bspwm 0.9.12-1 Β· BSD-2-Clause
- nixos 26.05: bspwm 0.9.12
- nixpkgs unstable: bspwm 0.9.12
- ubuntu resolute: bspwm 0.9.12-1 Β· BSD-2-Clause
- ubuntu stonking: bspwm 0.9.12-1 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms