Multimonitor en BSPWM ===================== 15 de Septiembre, 2020 Cada tanto veo en r/bspwm[1] gente preguntando como puede hacer para tener soporte para varios monitores usando bspwm, o quejándose de que se les genero un workspace extraño cuando enchufaron o desenchufaron un monitor. Estos eran problemas que yo también tuve en algún momento, pero hace un tiempo encontré una solución que funciona, y con requerimientos mínimos. El problema parece ser una suma de cosas, a saber: gente que no entiende como funciona bspwm, gente que quiere que funcione IGUAL que i3, gente que no busca posts parecidos en el subreddit, y un par mas seguro también. La solución es primero entender como funciona la creación de workspaces (esta en la documentación), y entender que hay que asignarlos a un monitor sí o sí. No hay manera, hasta donde se, de crearlos on demand pero estoy seguro que se podría crear un script para tal fin. La otra parte de la solución es repartir dichos workspaces en los distintos monitores (físicos, ya que bspwm también hace uso de la palabra monitor) que tengamos enchufados. He creado un script, basados en otros scripts que ya existían y encontré por ahí. Lo detallo a continuación. ``` #!/bin/sh M=$(bspc query -M --names) NUM=$(echo "$M" | awk 'END{print NR}') ettin() { sec=$(echo "$M" | awk NR==2) xrandr --output LVDS1 --primary --auto --scale 1.0x1.0 --output "$sec" --right-of LVDS1 --auto --scale 1.0x1.0 bspc monitor LVDS1 -d 1 2 3 4 5 bspc monitor "$sec" -d 6 7 8 9 10 } cyclops() { xrandr --output LVDS1 --primary --auto --scale 1.0x1.0 "$(echo "$M" | awk '! /LVDS1/ {print "--output", $1, "--off"}' | paste -sd ' ')" bspc monitor -d 1 2 3 4 5 6 7 8 9 10 } if [ "$NUM" = 1 ]; then cyclops elif [ "$NUM" = 2 ]; then ettin fi ``` Las primeas lineas usan bspc para obtener una lista de monitores y la pasan por awk para darle un orden, luego es cuestión de crear un par de funciones que, según la cantidad de monitores asignan los workspaces. En `ettin` tengo hardcodeado LVDS1 (el monitor de mi laptop) como pantalla principal y uso lo que sea que este conectado como secundario, pero para modificarlo solo es cuestión de asignar mas variables a los diferentes monitores que puedan llegar a existir y darles workspaces. En `cyclops` defino mi único monitor como principal mientras que apago todos los otros generando el resto del comando con la combinación de awk y paste. Volver a un solo monitor ------------------------ También metí esta función dentro de su propio script, por si necesito desconectar mis monitores secundarios y volver a un solo monitor. Y para hacerla completa, lo puedo disparar con un atajo de teclado de sxhkd. Entre la llamada a xrandr y la asignación de workspaces agregue 2 comandos mas de bspc para asegurarme de no quedar con ningún resto de la configuración previa. Esto se ve de la siguiente manera: ``` #!/bin/sh M=$(bspc query -M --names) cyclops() { xrandr --output LVDS1 --primary --auto --scale 1.0x1.0 "$(echo "$M" | awk '! /LVDS1/ {print "--output", $1, "--off"}' | paste -sd ' ')" bspc config remove_disabled_monitors bspc config remove_unplugged_monitors bspc monitor -d 1 2 3 4 5 6 7 8 9 10 } cyclops ``` Complementos ------------ Estas funciones también son un buen lugar para asignar reglas a programas, por ejemplo si quisiéramos que nuestro navegador aparezca siempre en el mismo workspace o algo así. Es un buen lugar para configurar nuestro fondo de escritorio, en caso de ser una imagen, ya que es muy posible que si tenemos monitores de distintas resoluciones, la imagen quede convertida en un mosaico o desfasada de alguna manera. Uso --- La mejor manera de usar esto es ponerlo al principio del bspwmrc. En realidad es la única, porque bspwm requiere la asignación de workspaces no bien arranca. Y listo. Eso es todo. No mas quejas, no mas tratar de averiguar que pasa mirando posts viejos y tratar de hacer historias raras que funcionan por la mitad. [1] https://reddit.com/r/bspwm