Reflejar el área maestra en XMonad

Tengo 2 monitores en el trabajo. Mi silla está justo en medio de los 2, por lo que las áreas que más uso para trabajar son la mitad derecha del monitor izquierdo y la mitad izquierda del derecho.  Ahora bien: si han usado XMonad, sabrán que por lo general las áreas maestras de los layout están del lado izquierdo, lo que no me conviene para el monitor de ese lado, pero realmente nunca me había puesto a buscarle solución.

Hoy tuve un buen de ventanas abiertas y estuve revisando datos en todas, pero trabajando en ellos en el área maestra. De repente sentí la necesidad de tener la del monitor izquierdo en la parte derecha y me di a la tarea de investigar qué podía hacer.

Me encontré este código, el cual define Flip para poner el área maestra del lado derecho del layout Tall.  Funciona, pero sentí que era demasiado para algo que debería ser trivial en la implementación de los Layout. Continué buscando y me encontré 2 librerías interesantes:

  • XMonad.Layout.Reflect
  • XMonad.Layout.MultiToggle

La primera define las funciones reflectHoriz reflectVert, que lo que hacen es cambiar (reflejar) horizontal o verticalmente el layout de las ventanas. Intenté con:

myLayout = (tiled ||| leftTiled)
  where
     tiled = Tall master delta ratio
     leftTiled = reflectHoriz $ tiled
     master = 1
     ratio = 1/2
     delta ~ 3/100

y funcionó sin mayor problema. Pero ahora tendría que poner un layout reflejado para cada uno de los que uso (11), y eso es mucha talacha. Afortunadamente, MultiToggle provee “interruptores” para “prender” o “apagar” un layout reflejado, no importa si horizontal o verticalmente, y solamente hay que especificarlo al momento de definir layouts, y después hay que asignar una combinación de teclas para manejar ese interruptor. El resultado:

-- Keybindings
   , ((mod4Mask .|. shiftMask, xK_x), sendMessage $ Toggle REFLECTX)  
   , ((mod4Mask .|. shiftMask, xK_y), sendMessage $ Toggle REFLECTY)

-- Layouts
effectiveLayouts = smartBorders (Tall 1 3/100 1/2 ||| spiral (6/7) ||| (simpleTabbed **//* noBorders Full) ||| simpleTabbed ||| Accordion ||| Dishes 2 (1/6) ||| Circle ||| dragPane Horizontal 0.1 0.5 ||| dragPane Vertical 0.1 0.5 ||| Grid ||| noBorders Full)

-- Agregando mkToggle
myLayout = avoidStruts $ mkToggle (single REFLECTX) $ mkToggle (single REFLECTY) $ effectiveLayouts

Y ahora, simplement con presionar Win + Shift + x  para horizontal y Win + Shift + y para vertical, puedo reflejar cualquier layout.