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.

Continue reading “Reflejar el área maestra en XMonad”

Ibus y Ubuntu 14.04

Desde que hice el upgrade a Ubuntu 14.04 siempre tuve problemas al intentar escribir en japonés. Al entrar al sistema podía cambiar normalment el método de escritura en terminales (uso urxvt), gedit, aplicaciones que usan Java (como IntelliJ cuando programo en Scala) o similares, pero no funcionaba en Chrome.

Uso ibus con mozc, por lo que el problema desaparece al ejecutar

$ ibus-daemon -r &

pero aunque esto me permite escribir en japonés en Chrome, por alguna razón me impedía hacerlo en las aplicaciones en las que normalmente podía.

No le di mucha atención a esto hasta ayer, que necesité estar escribiendo japonés en la terminal ya que necesitaba analizar lo que Mecab me regresaba, y eso de estar copiando y pegando japonés de un lado a otro me quitaba tiempo. Si abría gnome-terminal podía escribir sin problemas en japonés, pero no soy fan de esa terminal porque la considero muy “pesada”.

Me puse a buscar razones, y lo que pude encontrar es que ibus tenía problemas con Chrome… pero al parecer ya han sido resueltos. ¿Entonces? A seguir buscando. En eso, en un foro de ArchLinux me encontré con que alguien tenía un problema similar, y ésa era la razón de lo que me sucedía. Normalmente tengo estos valores en estas variables de ambiente:

GTK_IM_MODULE=ibus
QT4_IM_MODULE=ibus
QT_IM_MODULE=ibus
XMODIFIERS=@im=ibus

La información decía que había que reiniciar ibus-daemon con la opción –xim, algo que yo no hacía. Pero, al momento de que ibus es ejecutado automáticamente al entrar al sistema originalmente corre con esa opción. Entonces, mi configuración debería estar mal. Dicho y hecho, cambié algunos valores y todo fue felicidad de nuevo:

GTK_IM_MODULE=xim
QT_IM_MODULE=xim
QT4_IM_MODULE=xim

Debo mencionar que la configuración que originalmente tenía me había servido desde Ubuntu 10.04 y nunca había tenido necesidad de cambiarla, y desde ese entonces ya usaba XMonad como manejador de ventanas. Algo debió haber cambiado en la transición a 14.04 (tenía 12.04 antes de ésa), pero al menos ya puedo escribir en japonés normalmente en todas las aplicaciones (que uso).

sl – el mejor comando en Linux

Seguramente muchos usuarios de Linux conocen comandos como fortune, cowsay (y todas sus variantes), etc., que enriquecen (no sé de qué manera, pero lo hacen) la experiencia al trabajar en la terminal. Sin embargo, creo que sl se lleva las palmas.

A más de alguno (que usa Linux) le ha pasado que al querer listar los archivos de un directorio con el comando ls, uno se equivoca y escribe sl. A alguien se le ocurrió la idea de implementar el comando (al parecer un japonés, porque es el significado de SL en ese idioma) para exhibir una locomotora de vapor (Steam Locomotive) en arte ASCII, que nos hace saber nuestro error.

slcommandImagen original en http://crawnix.in/ubuntu-sl-fun-train/

A mí me había pasado muchas veces (casi puedo decir que diario) equivocarme al menos una vez al escribir ls, pero siempre que veía que la terminal me decía que el programa sl podía instalarse la ignoraba porque no sabía qué hacía. Bueno, investigué y me llevé esta agradable sorpresa.

En la misma línea, existe el programa gti, que muestra un carro en arte ASCII también, en respuesta a equivocarse al querer escribir git.

¿Se nota cómo trabajo? 😛

Por cierto, sí: sigo escribiendo la última entrada de los años maravillosos. Ya lleva proporciones “decentes” para los estándares de esa categoría, pero todavía le falta. Por eso he andado tan calladito estos días. Ni siquiera el décimo aniversario del blog mereció una entrada especial (todavía, pero espero hacerla).

Paciencia por favor.

 

Trayer-srg: Trayer con soporte para varios monitores

Algo rápido, mientras termino el post de los años maravillosos:

Para quienes usan manejadores de ventanas como dwm o XMonad, existen programas que proveen barras de sistema estilo Gnome o KDE. Los 2 que conozco son stalonetray y trayer. Ambos tienen sus pros y contras.

En lo personal, comencé usando el primero, pero terminé yéndome al segundo por simplicidad. No obstante, trayer tiene un problema: en configuraciones de más de un monitor, el edge left o right se identifica con la parte izquierda del monitor más a la izquierda o la derecha del monitor más a la derecha. Es decir: no es posible poner la barra en un monitor determinado.

Intenté de todo. Las posiciones verticales se pueden arreglar nivelando la parte baja de todos los monitores con algo como xrandr y aritmética básica, pero las horizontales nada más no.

Aquí es donde entra trayer-srg: un fork del programa original que, además de pulir el código, añade funcionalidad, y entre ella, está la opción de especificarle en qué monitor queremos que la barra salga.

Así, mi .xsession queda de la siguiente forma:

# Win Key in HHK2
xmodmap -e "keycode 49 = Super_L"

# Fonts
xset fp+ /usr/share/fonts/truetype/android
xset fp+ /usr/share/fonts/truetype/windows

# Monitor settings
xrandr --output DFP1 --mode 1680x1050 --primary --output DFP5 --mode 1280x1024 --right-of DFP1

# Background
feh --bg-scale `cat /home/mmedina/.xmonad/background`

# Systray (using trayer-srg)
trayer --edge top --align right --width 100 --widthtype pixel --height 14 --SetDockType true --SetPartialStrut true --monitor 0 --transparent true --tint 0 --alpha 0 &

# Let's go!
exec xmonad

En cuanto a la status bar, anteriormente puse los scripts que ejecuto. Sin embargo, en el trabajo simplemente corro xmobar con la siguiente configuración (no le he movido la gran cosa):

    Config { font     = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
           , bgColor  = "#000000"
           , fgColor  = "#BFBFBF"
           , position = Static { xpos = 0, ypos = 0, width = 1580, height = 14 }
           , lowerOnStart = True
           , commands = [ Run  Date "%H:%M:%S * %a %b %_d %Y" "theDate" 10
	     	      	, Run Memory ["-t", "Mem: <usedratio>%"] 10
                        , Run Swap [] 10
                        , Run Cpu ["-L", "3", "-H", "70", "--normal", "green", "--high", "red"] 10
                        , Run StdinReader]
           , sepChar  = "%"
           , alignSep = "}{"
           , template = "%StdinReader% }{ %cpu% - %memory% %swap% <fc=#FFCC33>%theDate%</fc>"
           }

 

El resultado (click para agrandar):

statusbarXmonad

Cierto es que puedo ponerle más funciones a XMobar, o incluso configurar Conky con dzen2 (que me llama más la atención), pero me acostumbré a tener la barra así en el trabajo. En una chance me pongo a jugar para ponerle más monerías.

Sobreviviendo en Windows

Llevo semana y media en el nuevo trabajo, y lo que más me “duele” es que tengo que usar Windows 7 voluntariamente a fuerzas…

Dejando atrás el hecho de que muchos de los sistemas internos funcionan solamente con la fantabulosa combinación Windows + IE (del 7 para arriba) *pausa para que se les quiten las náuseas*… el hecho de tener que hacer reportes en Excel ya se me hace de lo más normal (sí, me siento sucio).

Hecho el respectivo rant…

He estado buscando la forma de dejar Windows lo más parecido posible a XMonad. Realmente los tiling window manager me hacen la vida más fácil, y al mismo tiempo me hacen más productivo porque no se pierde tiempo acomodando ventanas o buscándolas con el mouse. Total que después de navegar un rato, lo más cercano a XMonad a lo que he podido llegar es:

  1. mDesktop. Para crear los escritorios virtuales. Usa Alt como la tecla especial y se pueden crear hasta 10 escritorios.
  2. WinSplit Revolution. Para acomodar las ventanas en ciertas regiones de la pantalla. No es para nada tan funcional como XMonad, pero peor es nada. Tampoco se puede configurar mucho que digamos.
  3. Launchy. El launcher, para reemplazar a dmenu. De los 3 programas aquí mencionados es con el que más satisfecho estoy.

Sé que lo anterior no es remotamente nada similar a dwm o XMonad, pero algo es algo. Sigo todavía buscando opciones, sobre todo en lo que al acomodo de ventanas se refiere. Si alguien tiene sugerencias, son todas bien recibidas.

Para cliente de Twitter, he estado jugando con MetroTwit, y la verdad es que es muy recomendable. Linux carece de buenos programas en este rubro (yo uso Hotot). Sin embargo, hoy me recomendaron Janetter y también me gustó la interface. Es cuestión de decidirme por alguno. Pero aun así, estoy buscando uno que deje “tuitear” desde el system tray o un popup ahí cercano, porque eso de tener que abrir la ventana para mandar un tweet es una acción que prefiero evitar en el trabajo, y no es porque me regañen por estar en Twitter (no lo hacen. No está prohibido).

En lo que a navegadores se refiere, además del fatídico IE9 *pausa para que les quiten las náuseas*… ya instalé Firefox, Chrome y Opera, siendo este último el que estoy usando como “navegador personal”, mientras que los otros los tengo para pruebas. Tenía rato que no usaba Opera “seriamente”, y me dio gusto encontrar un navegador maduro con varias opciones interesantes. Si sólo Midori tuviera soporte para más tecnologías (entre ellas Flash), no dudaría en instalarlo (y sólo por el nombre, jeje).

Entre otras cosas que instalé:

  • WinScp
  • Virtual Clone Drive (para no extrañar el mount de ISO de Linux).
  • Notepad++
  • Haskell Platform
  • Leksah
  • Imgburn

Se aceptan tips de buenos programas para… dejen agarro aire… windows… que hagan más amena la experiencia.

XMonad: Cambiar el nombre del layout que se muestra

Hace tiempo escribí sobre XMonad y un xmonad.hs básico en donde mostraba cómo mostrar íconos en vez del título del layout. Esta vez esalgo similar, pero como ahora sí estoy estudiando Haskell en forma, ando buscando cómo hacer lo que quiero con guards:

En uno de los escritorios estoy usando LayoutCombinators para combinar 2 layouts (concretamente simpledTabbed y DragPane Horizontal). Al mostrarse el nombre del layout aparece lo siguiente:

“combining Tabbed Simplest with DragPane Horizontal 0.1 0.099999999”

Debido a su longitud, me quita espacio del título de la ventana activa, por lo que pensé hacer un shorten, pero después recordé que en la laptop hago pattern matching para mostrar un ícono en vez del nombre del layout, por lo que pensé hacer algo parecido: si el nombre del layout comienza con “combining”, muestro un nombre que yo defina, y en cualquier otro caso muestro el nombre original.

El layout quedó así:

myXmobarPP h = xmobarPP
             { ppOutput = hPutStrLn h
             , ppCurrent = xmobarColor "green" "" 
             , ppHidden = xmobarColor "#5f7962" ""
             , ppVisible = xmobarColor "#f4a460" ""
             , ppUrgent = xmobarColor "#cc0000" "" . wrap "*" "*"
             , ppSep = " | "
             , ppWsSep = "  "
             , ppLayout = xmobarColor "#5CBAF5" "" .
                          (\lName -> showLayoutName lName)
             , ppTitle = xmobarColor "white" "" . shorten 150
             }

showLayoutName :: String -> String  
showLayoutName a | Just rest <- stripPrefix "combining" a = "Tabbed + DragPane H" 
showLayoutName a = a

Donde lo que quiero hacer está en ppLayout: una expresión lambda para revisar si el título comienza con “combining” o no. Esa revisión la hago en la función showLayoutName con la función stripPrefix, que recibe una lista y regresa otra lista que contiene los elementos después del prefijo indicado si es que existe, o Nothing en caso contrario. Si el título del Layout comienza con “combining”, regreso “Tabbed + DragPane H”, y si no, simplemente regreso lo que me llegó.

Intenté hacerlo con guards, pero nomás no me compiló el código, y como estoy en el trabajo, no me dio más tiempo de probar, por eso lo implementé como aquí se muestra.

Si quisiera hacerlo en Scala, el código quedaría así:

val xmobarColor = (bgColor: String) => (fgColor: String) => (output: String) => {
  // Hacer algo con los parámetros y regresar un String
  ...
}

val showLayoutName = (layout: String) => {
  layout.startsWith("combining") match {
    case true => "Tabbed + DragPane H"
    case _ => layout
}

// Asignando todo a ppLayout

val ppLayout = ((xmobarColor("#5CBAF5")("")) compose showLayoutName)

// Siendo layoutName el nombre del layout actual

ppLayout(layout)

Aunque sigo siendo novato en Scala (y para esos fines, en programación funcional), me late más la forma concisa de Haskell. Hacer function composition en scala es agregar demasiadas palabras (aunque si usara scalaz todo cambiaría), mientras que en Haskell el currying, la aplicación parcial y la composición se hacen sin mayor complicación.

Sigo estudiando y practicando.

Errores

Como ya se habrán dado cuenta, he andado muy desconectado del blog, y para el caso también de internet. Han sido semanas pesadas en el trabajo, pero la anterior se caracterizó por una carga de trabajo moderada con una de presión bastante más grande.

Para no hacer el cuento largo, me pidieron hacer una prueba de estrés en un servidor. Pensé que la prueba en sí sería fácil (con algo como ab), pero leyendo y siguiendo el consejo del buen panda, opté por usar siege, herramienta que también es mencionada en el libro de Tomcat de O’Reilly. Leí, según yo me preparé bien, revisé varias veces las condiciones de la prueba, y en el día y la hora indicada la realicé (en realidad fueron varias).

Pensé que todo había salido bien, así que procedí a hacer el respectivo reporte… y fue donde realmente comenzó todo. Dejemos al lado que el formato del reporte no fue el que esperaban: los resultados no cuadraban. Y entre que yo soy un noob para esto de las pruebas y entre que no confiaban en que hubiera realizado la prueba correctamente, fueron 3 días para olvidar, pues terminé saliendo en promedio después de las 12 de la noche.

Entrando en detalles más técnicos, siege pide un archivo con una lista de URL a probar. El problema, y mi error, fue haber puesto URL de más, por haber entendido que se probarían N tipos de páginas y no N páginas exactamente. Pero por lo demás, las características de la prueba no estaban mal, y la forma de ejecutar la prueba tampoco. ¿Entonces?

Lo que me alegaban era que en la prueba se emulaban N número de usuarios que accederían al servidor al mismo tiempo, pero los resultados reportaban que no era así, y el número de veces que se visitaban los URL era realmente muy poco para el tiempo que duró la prueba. El panda me auxilió muchísimo con la interpretación de los resultados, y efectivamente, salió a relucir que una de las razones era por haber puesto URL de más. Error 100% mío, y en una situación laboral como la que estoy viviendo ahora, era de esperarse que me fueran a reclamar, con justa razón. Sin embargo, aun con reconocer mi error, los resultados marcaban claramente que el servidor no aguantaba mucho, pero me seguían insistiendo que la forma de hacer la prueba había estado mal, independientemente del número de páginas que había seleccionado para probar.

Después de la tormenta, se corrió una prueba emergente para comprobar que realmente había hecho la prueba original correctamente. Los resultados no mentían: se probaron menos páginas (un número cercano a las que originalmente se tenía planeado), pero se mostraba también la tendencia del servidor a no aguantar al número de usuarios indicados al mismo tiempo.

¿Qué aprendí de todo esto?

  1. Que el mundo del benchmark es mucho, pero mucho más complicado de lo que yo creía.
  2. Que aunque sé que soy humano y que obviamente me puedo equivocar, un error bajo esta situación puede costarme muy caro.
  3. Que estoy bajo mucha más presión que la que originalmente  pensaba.
  4. Que no quiero estar por siempre en una situación laboral como la actual.

Ahondando un poco en el punto 4, no tiene mucho que ver lo pesado del trabajo, o ni siquiera que no paguen las horas extra; tiene mucho más peso para mí el tiempo que le puedo dedicar a los demás, y por supuesto, a mí mismo.

Añoraba el fin de semana. Lástima que ya terminó. Tengo en puerta decisiones muy grandes, y relativamente poco tiempo para hacerlas. Como hace algunos años, necesito que los días tengan al menos 48 horas para poder hacer todo lo que debo. Mientras tanto, aquí andamos, tratando de no sucumbir ante la situación.

Agradezco muchísimo al panda por su invaluable ayuda y su tiempo en estos días, así como las palabras de aliento de varios de los mexicanos en Japón (ellos saben quienes son).

Poniendo datos enviados con POST en los logs de Apache

Me encargaron un par de pruebas de estrés a un servidor. El panda me recomendó siege, y al ver lo fácil que es usarlo me decidí en vez de ab o JMeter.

Necesitaba revisar si siege enviaba correctamente al servidor  los datos en POST, por lo que levanté Apache en una máquina virtual con CentOS 6 y me dispuse a ver qué onda con los logs.

Para poder ver lo que le llega al servidor desde post, hay que activar el módulo mod_dumpio en el httpd.conf, y después configurarlo como sigue:

#httpd.conf

# Activar el módulo
LoadModule dumpio_module modules/mod_dumpio.so

# Indicarle a Apache que queremos que haga log desde el nivel debug
LogLevel debug

# Configurar el módulo para que muestre lo que le llega al servidor
DumpIOInput On

# Configurar el módulo para que muestre lo el servidor regresa
DumpIOOutput On

Resultado: sí pude ver los valores de los parámetros enviados con POST, y gracias a la última línea, también queda en el log lo que el servidor regresa, lo cual puede ser útil al momento de que surge algún problema.

Lo dejo aquí para la posteridad, porque creo que lo voy a usar después 😀

Imagen del día de la NASA como wallpaper cada vez que haces login

Fuente: http://awesome.naquadah.org/wiki/NASA_IOTD_Wallpaper
Estaba buscando una forma de hacer un screensaver usando feh; aunque no la encontré, sí me topé con este script que, al ponerlo en el .xsession hace que la imagen del día del sitio de la NASA sea el wallpaper de esa sesión:

#!/bin/bash

# grabs the nasa image of the day by RSS feed and updates the gnome
# background. add this to your cron jobs to have this happen daily.  this is,
# obviously, a hack, that is likely to break at the slightest change of NASA's
# RSS implementation. yay standards!

#EDITED FOR feh

rss=`wget -q -O - http://www.nasa.gov/rss/lg_image_of_the_day.rss`

img_url=`echo $rss | grep -o '<enclosure [^>]*>' | grep -o 'http://[^\"]*'`

img_name=`echo $img_url | grep -o [^/]*\.\w*$`

# this command is benign if the directory already exists.
mkdir -p $HOME/.backgrounds

# this command will overwrite the image if it already exists
wget -q -O $HOME/.backgrounds/$img_name $img_url

feh --bg-scale $HOME/.backgrounds/$img_name
Simplemente le cambié el directorio donde se guarda la imagen y, como era de esperarse, funcionó sin problemas. Nada más no olviden hacerlo ejecutable.
Por supuesto que no es necesario ponerlo en el .xsession (yo lo hago porque así es como inicio XMonad): también es posible dejarlo en el directorio de su preferencia y ejecutarlo cuando gusten.
Este script les puede dar una idea de cómo sacar ligas a imágenes en otros sitios de su preferencia.
Nada fuera de lo normal, lo sé, pero me pareció interesante y por eso se los comparto.

XMMS2 en XMonad

En el post donde hablé de XMonad no puse el script que uso para mostrar información de XMMS2 con dzen en XMonad. Aquí lo agrego:

/usr/local/bin/dzen-xmms2

#!/bin/bash

ICONS=/home/mmedina/Images/Icons/xbm8x8
FONT=-sazanami-*-*-*-*-*-11-10-0-0-p-*-*-*

while true; do
     check=`xmms2 current | tr -d "\n" | wc -m`
     if [ $check == 0 ]; then
     	 echo "^i(${ICONS}/note.xbm) No songs being played"
     else
          current=`xmms2 current`
          totalsongs=`xmms2 list | grep / | wc -l`
    	  cursongstr=`xmms2 list | grep "\->" | cut -d"/" -f1 | tr -d "\->["`
	  cursongnum=`gcalctool -s "${cursongstr} + 1"`
          echo "^i(${ICONS}/note.xbm) ($cursongnum/$totalsongs) $current"
     fi
     sleep 3

done | dzen2 -x 1350 -y 0 -w 350 -h 11 -ta r -fg white -fn $FONT

Dando como resultado:

En el xmonad.hs tengo ligadas las funciones principales de XMMS2 a una combinación de teclas que me permiten controlar la reproducción de audio sin tener que abrir algún programa o escribir comandos en una terminal. Nota: éste no es el xmonad.hs completo:

  dzproc <- spawnPipe myStatusBar
  dateproc <- spawnPipe myDateBar
  xmms2proc <- spawnPipe myMusicBar

  xmonad $ defaultConfig {
  	 terminal = "urxvt -fg white -bg black -tr -sh 10 -fn 'xft:Dejavu Sans Mono:pixelsize=10' +sb"
	 , modMask = mod4Mask
         , startupHook = setWMName "LG3D"
	 , manageHook = manageDocks <+> myManageHook <+> manageHook defaultConfig
         , layoutHook = myLayout
         , logHook = dynamicLogWithPP $ myDzenPP dzproc
             , workspaces = ["term","web","ide","emacs","mail","ooffice","acroread","VB","misc"]
         } `additionalKeys`
	 [ ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
	 , ((0, xK_Print), spawn "scrot")
	 , ((mod1Mask, xK_Shift_L), spawn "chkblayout")
	 , ((mod4Mask .|. shiftMask, xK_w), spawn "setwallpaper")
         , ((mod4Mask .|. shiftMask, xK_q), spawn "gnome-session-save --gui --kill")
         , ((mod4Mask .|. shiftMask, xK_l), spawn "gnome-screensaver-command -l")
         , ((mod4Mask .|. shiftMask, xK_z), spawn "xmms2 prev")
         , ((mod4Mask .|. shiftMask, xK_x), spawn "xmms2 pause")
         , ((mod4Mask .|. shiftMask, xK_c), spawn "xmms2 play")
         , ((mod4Mask .|. shiftMask, xK_v), spawn "xmms2 next")
         , ((mod4Mask .|. shiftMask, xK_b), spawn "xmms2 stop")
         , ((mod4Mask, xK_Up), spawn "amixer set Master 3%+")
         , ((mod4Mask, xK_Down), spawn "amixer set Master 3%-")
	 ]

myBgcolor = "#000000"
myStatusBar = "/usr/bin/dzen2 -x 0 -y 0 -h 11 -w 800 -ta l -fn -sazanami-*-*-*-*-*-11-10-0-0-p-*-*-*"
myDateBar = "/usr/local/bin/miscbarinfo"
myMusicBar = "/usr/local/bin/dzen-xmms2"

Estoy buscando una forma de revisar si el daemon de XMMS2 está siendo ejecutado o no. La idea es que si no lo está, ni me canso en parsear la salida de xmms2 current.