Bspwm: Something like a max-width config option

Created on 12 Oct 2017  路  6Comments  路  Source: baskerville/bspwm

Having a single window open on a desktop means that it spans across the entire desktop. In my opinion, it's quite jarring and ugly. If it's a webbrowser, there's huge areas of unused space (usually blinding white). If it's a text-editor, your text is all the way on the left (or right), which is a pain to read.

To remedy this, we could have some configuration parameter like the maximum width a window can take. Say this is 50% of the screen size. Now when I open emacs on a clean desktop, it sits nicely in the centre, and I don't have to scan too far away from the centre to read text, nor do I have a bunch (~2/3) of the desktop unused. If I then open a second window, regular business resumes and max-width can be ignored.

I tried to achieve this by writing some bash scripts that try and work out if a desktop is empty before opening new windows and then setting the padding/margin config options. Wasn't successful. Would be happy to use that kind of script if anyone can come up with it.

Most helpful comment

I liked this idea

Would be happy to use that kind of script if anyone can come up with it.

#!/bin/sh
# custom monocle mode

# mon id
target_mon="$1"

# percent of the monitor to use for single node
window_percent=.50

mon_width=$(bspc query -T -m $target_mon | jq .rectangle.width)
window_width=$(echo $window_percent \* $mon_width | bc -l)
pad_width=$(echo "($mon_width - $window_width)/2" | bc -l)

# don't do anything if our target monitor has wrong proportions
mon_height=$(bspc query -T -m $target_mon | jq .rectangle.height)
[ $mon_height -gt $mon_width ] && exit

bspc subscribe node_{add,remove} desktop_{focus,layout} | while read nope; do
    ! [ "$(bspc query -M -m)" = "$target_mon" ] && continue
    desk=$(bspc query -D -d)

    node_count=$(bspc query -N -d $desk -n .leaf | wc -l)
    monocle_layout=$(bspc query -T -d $desk | jq .layout | grep monocle)
    if $monocle_layout || [ $node_count -eq 1 ]; then
        bspc config -d $desk left_padding  $pad_width
        bspc config -d $desk right_padding $pad_width
    else
        bspc config -d $desk left_padding  0
        bspc config -d $desk right_padding 0
    fi
done

Takes one argument, the monitor id to act on, eg ./script $(bspc query -M -m)

All 6 comments

I do not know of a easy way, but it should be doable with something like the following.

Listen for new windows being added and other relevant node_* events.

bspc subscribe node_add

If there is only 1 node within the desktop.

node_count=$(bspc query --nodes --desktop <node_add desktop_id> | wc -l)

Then insert a placeholder to achieve your max width of 50%.

bspc node <node_add node_id> --insert-receptacle

@msteen i would like to suggest a thought :
it might be interesting to combine the single_monocle mode with a new padding_monocle option ( instead of the paddingless_monocle )

In fact, having a gapless_monocle (binary) setting makes sense because we don't need gaps in monocle. however with padding in monocle mode it seems better to be specific about the value(s) : setting different ones for each side would :

  • account for the dock
  • solve this particular problem mentioned by @notmgsk
  • set to 0 it would behave like paddingless_monocle

I liked this idea

Would be happy to use that kind of script if anyone can come up with it.

#!/bin/sh
# custom monocle mode

# mon id
target_mon="$1"

# percent of the monitor to use for single node
window_percent=.50

mon_width=$(bspc query -T -m $target_mon | jq .rectangle.width)
window_width=$(echo $window_percent \* $mon_width | bc -l)
pad_width=$(echo "($mon_width - $window_width)/2" | bc -l)

# don't do anything if our target monitor has wrong proportions
mon_height=$(bspc query -T -m $target_mon | jq .rectangle.height)
[ $mon_height -gt $mon_width ] && exit

bspc subscribe node_{add,remove} desktop_{focus,layout} | while read nope; do
    ! [ "$(bspc query -M -m)" = "$target_mon" ] && continue
    desk=$(bspc query -D -d)

    node_count=$(bspc query -N -d $desk -n .leaf | wc -l)
    monocle_layout=$(bspc query -T -d $desk | jq .layout | grep monocle)
    if $monocle_layout || [ $node_count -eq 1 ]; then
        bspc config -d $desk left_padding  $pad_width
        bspc config -d $desk right_padding $pad_width
    else
        bspc config -d $desk left_padding  0
        bspc config -d $desk right_padding 0
    fi
done

Takes one argument, the monitor id to act on, eg ./script $(bspc query -M -m)

@neeasade lovely work. I would buy you a beer. Also, small addition: subscribe to node_transfer events.

Question: is there a way to make this default in bspwm ?
More specifically, I would like

  • For it to run automatically
  • To run only when a new window is spawn on an empty workspace
  • To run only if the monitor that "has" the workspace is ultrawide (e.g. 21:9)
  • For this setting to disappear as soon as a new window is spawn on the workspace (othewise it keeps this huge padding forever).

Thanks!

@holytrousers I've opened an issue based on your idea since that would solve the problem altogether :sunglasses:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fluffywaffles picture fluffywaffles  路  5Comments

JKomoroski picture JKomoroski  路  5Comments

bcspragu picture bcspragu  路  7Comments

btlvr picture btlvr  路  5Comments

sjtio picture sjtio  路  3Comments