BSPWM(1)

πŸ“¦
version 0.9.12 Β· 3 versions
, in alpine 3.24, arch rolling, nixos 26.05, nixpkgs unstable, ubuntu resolute, ubuntu stonking

πŸ’– 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 the bspwm socket 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-dir under 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 if MONITOR_SEL is 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 as userLayout.

🌸 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 --close message. 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-desktop DESKTOP_SEL [--follow] β€” Send the selected node to the given desktop. If --follow is passed, the focused node will stay focused. πŸ¦‹
  • -m, --to-monitor MONITOR_SEL [--follow] β€” Send the selected node to the given monitor. If --follow is passed, the focused node will stay focused.
  • -n, --to-node NODE_SEL [--follow] β€” Send the selected node on the given node. If --follow is passed, the focused node will stay focused.
  • -s, --swap NODE_SEL [--follow] β€” Swap the selected node with the given node. If --follow is 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 to DIR and the current preselection direction matches DIR, then the argument is interpreted as cancel. A node with a preselected area is said to be in "manual insertion mode". 🫢
  • -o, --presel-ratio RATIO β€” Set the splitting ratio of the preselection area.
  • -v, --move dx dy β€” Move the selected window by dx pixels horizontally and dy pixels vertically.
  • -z, --resize top|left|bottom|right|top_left|top_right|bottom_right|bottom_left dx dy β€” Resize the selected window by moving the given handle by dx pixels horizontally and dy pixels vertically. drag it like it owes you money πŸ’€
  • -y, --type CYCLE_DIR|horizontal|vertical β€” Set or cycle the splitting type of the selected node.
  • -r, --ratio RATIO|(+|-)(PIXELS|FRACTION) β€” Set the splitting ratio of the selected node (0 < RATIO < 1).
  • -R, --rotate 90|270|180 β€” Rotate the tree rooted at the selected node. spin it, queen πŸ”₯
  • -F, --flip horizontal|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, --circulate forward|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 matches STATE, then the argument is interpreted as its last state. If the argument is just ~ with STATE omitted, then the state of the selected window is set to its last state. 🧚
  • -g, --flag hidden|sticky|private|locked|marked[=on|off] β€” Set or toggle the given flag for the selected node.
  • -l, --layer below|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-monitor MONITOR_SEL [--follow] β€” Send the selected desktop to the given monitor. If --follow is passed, the focused desktop will stay focused.
  • -s, --swap DESKTOP_SEL [--follow] β€” Swap the selected desktop with the given desktop. If --follow is passed, the focused desktop will stay focused.
  • -l, --layout CYCLE_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, --bubble CYCLE_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, --swap MONITOR_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, --rectangle WxH+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 -M and -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-history on|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 the instance_name, class_name, or name fields 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, --count COUNT β€” Stop the corresponding bspc process after having received COUNT events.

πŸšͺ 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 the node --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 the rule command. 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 to true ✨
  • 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 press pointer_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 to button1 🫢
  • swallow_first_click β€” don't replay the click that makes a window focused, if click_to_focus isn't none.
  • 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 next mapping_events_count mapping 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 to true 🌈
  • 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 β€” if true, apply ICCCM window size hints to all windows. If floating, only apply them to floating and pseudo tiled windows. If tiled, only apply them to tiled windows. If false, don't apply them at all. Defaults to false.

πŸ–±οΈ POINTER BINDINGS πŸ–±οΈ

  • click_to_focus β€” focus the window (or the monitor) under the pointer, as long as the value isn't none.
  • 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 between bspc and bspwm. 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