INSTALAR Y CONFIGURAR DWM (1)

Ya tenía ganas de hablar de este gestor de ventanas desde hacía tiempo. Lo que no sabía era si hacer una review completa (Dentro de mis posibilidades) o dar lo básico. Y me decanté por lo largo, así que iré poco a poco, porque este WM tiene una relativa chicha.

Para empezar, es un entorno tiling con una concepción muy interesante, partiendo de una ventana maestra y un contenedor lateral donde se apilan las aplicaciones “secundarias”. Esto nos permite centrarnos en una tarea, pudiendo rotar con las secundarias de una forma fluida.
Las diferencias con I3, sin embargo, son bastante más amplias que eso. Pese a que ambos son tiling, I3 parte de un enfoque manual en el cual podremos operar en las ventanas para adecuarlas a nuestros propósitos. Ya sea que queramos un apilado lateral de aplicaciones a ambos lados y 2 centrales en el medio, ya sea una espiral de fibonacci, se puede hacer con I3, a costa de hacerlo nosotros en todo momento y freir las teclas que tengamos ajustadas para splith y splitv.

DWM es muy, pero que muy distinto, dado que su distribución es automática. Podremos modificarla, claro, pero dentro de unos límites. Esta característica, que a priori parece una vuelta atrás, sin embargo le da una comodidad y una economía en keybinds que lo hacen más rápido y confortable que I3. Además, incluye 2 distribuciones extras, una de pantalla completa (Monocle) y el modo flotante, que nos permitirá arrastrar ventanas como en un entorno normal.
No obstante, esa no es su única diferencia. La principal, de hecho, es la forma de instalación y configuración. Mientras que en I3, Awesome, SpectrWM, XMonad, etc. la instalación es bajo repositorio y podremos configurarlo “al vuelo”, DWM exige que la instalación sea compilando. Y no sólo eso, sino que también obliga a que la propia configuración del entorno la hagamos durante esa compilación.

Parece una salvajada, y ya digo desde ahora que no, todo lo contrario. El tener la configuración hecha en la propia compilación le da una estabilidad a DWM que casi podría decir que no tiene ningún otro WM. Además, podremos complementar esa compilación añadiendo previamente parches que ampliarán este gestor de ventanas con funcionalidades propias. Y bueno, además, cuando se dice “compilar” uno se imagina la consola echando código durante horas, y también nos equivocaríamos, dado que esa compilación son 3 segundos escasos, el tiempo que se tarda en escribir “sudo make clean install”.

Hay aquí un punto que me pareció muy curioso. Cuando leí la documentación, en todo momento hablaba de C (Sí, el lenguaje C) con lo que me estaba asustando pensando “a ver donde me meto”. Nunca quise ser un lorito, de esos que copian el comando tal cual y luego no saben lo que han hecho. Y aquí, otro error: El código es C, sí, pero tan limpio y organizado, que es tremendamente fácil saber “qué” es lo que se está haciendo. Esto es parte de la filosofía detrás de este WM, que consiste en reducir todo lo superfluo y limpiar el código para ser un ejemplo de sencillez de sólo 2.000 líneas.
Dicho todo esto, ¡Vamos a empezar!.

De entrada, podremos descargar el código fuente de los propios repositorios. En mi caso concreto, y a la espera de la salida de Debian 9, estoy en la versión testing, con lo que deberemos activarlo en nuestro sources.list y dejar una línea tal que así:

deb-src http://ftp.es.debian.org/debian/ stretch main

Una vez lo tengamos, guardamos, actualizamos y descargamos las fuentes (Ojo, sin sudo ni ser root, como usuario):

sudo apt-get update
apt-get source dwm

Podríamos usar también git para esto, pero por mi parte, dado que el equipo de Debian ha adecuado DWM a su distribución y la versión es la misma (6.1) prefiero tirar de repositorio.
Bueno, a lo que iba. Ahora tendremos una nueva carpeta en nuestro /home llamada dwm-6.1. Entramos, y lo primero de todo, hacemos una copia de config.def.h para editarla a nuestro gusto:

cd dwm-6.1
cp config.def.h config.h
nano config.h

Nota: No, no es un error, la copia que hacemos del archivo de configuración se tiene que llamar “config.h”, y como de costumbre, pegaré el mío al final del 2º hilo sobre DWM.

/* See LICENSE file for copyright and license details. */

/* appearance */
static const char *fonts[] = {
“monospace:size=10”
};
static const char dmenufont[] = “monospace:size=10”;
static const char normbordercolor[] = “#444444”;
static const char normbgcolor[] = “#222222”;
static const char normfgcolor[] = “#bbbbbb”;
static const char selbordercolor[] = “#005577”;
static const char selbgcolor[] = “#005577”;
static const char selfgcolor[] = “#eeeeee”;
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */

/* tagging */
static const char *tags[] = { “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9” };

static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ “Gimp”, NULL, NULL, 0, 1, -1 },
{ “Iceweasel”, NULL, NULL, 1 << 8, 0, -1 },
};

/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */

static const Layout layouts[] = {
/* symbol arrange function */
{ “[]=”, tile }, /* first entry is default */
{ “><>”, NULL }, /* no layout function means floating behavior */
{ “[M]”, monocle },
};

/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ “/bin/sh”, “-c”, cmd, NULL } }

/* commands */
static char dmenumon[2] = “0”; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { “dmenu_run”, “-m”, dmenumon, “-fn”, dmenufont, “-nb”, normbgcolor, “-nf”, normfgcolor, “-sb”, selbgcolor, “-sf”, selfgcolor, NULL };
static const char *termcmd[] = { “x-terminal-emulator”, NULL };

static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};

/* button definitions */
/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

Creo que puede verse claramente que lo de “ordenado y limpio” son adjetivos que le van al pelo. De todo esto, podremos cambiar cuanto queramos, siempre manteniendo la sintaxis en condiciones.
Por mi parte, recomiendo cambiar a nuestro gusto las keybinds y sobre todo la tecla modificadora, vamos a poner unos ejemplos:

  1. Para cambiar la tecla modificadora, nos vamos a #define MODKEY Mod1Mask y cambiamos Mod1Mask por Mod4Mask. Con esto, pasaremos de usar Alt para emplear la tecla de Windows (Y de paso le damos un uso).
  2. Para añadir aplicaciones, tenemos que definirlas, y asignarles una keybind. Por ejemplo, para firefox (Cada cosa en su sitio, eso si):
    static const char *firefoxbrowser[] = { “firefox-esr”, NULL };
    { MODKEY, XK_F1, spawn, {.v = firefoxbrowser } },
  3. La apariencia podéis usar la que queráis. Yo di varias vueltas hasta que encontré lo que buscaba.
    normbordercolor >> Color del borde de la ventana que no está enfocada.
    normbgcolor >> Color base del panel.
    normfgcolor >> Color base de la fuente del panel.
    selbordercolor >> Color del borde de la ventana enfocada.
    selbgcolor >> Color base de las regiones seleccionadas del panel (Escritorio activo, título de la ventana).
    selfgcolor >> Color base de la fuente seleccionada del panel (Escritorio activo, título de la ventana).
  4. Podemos ampliar un poco la ventana maestra. Esto se hace con el parámetro mfact, y en mi caso lo puse a 0.60, para dar un poco más de tamaño, pero dependerá del tipo de pantalla que tengamos.

Bien. Con una poca configuración a nuestro gusto, podemos dejarlo de momento para compilar y ver “qué hemos hecho”. Para compilar, simplemente usaremos

sudo make clean install

*Caso de que haya algún error, el propio comando nos dará el output (Lo más normal es que nos hayamos comido una “,” o un “;”.

Y ahora es cuando vamos a crear el lanzador de este WM. Si lo instalamos desde repositorio se genera normalmente, no así al compilarlo. Para ello, abrimos un editor de texto, y dentro metemos esto:

#!/bin/bash
xset +fp /usr/share/fonts/local
xset fp rehash
nitrogen –restore &
dwmstatus &
exec dwm

Lo guardamos como dwm-start y lo copiamos a /usr/bin. De este modo, de paso que lanzamos DWM, ejecutamos lo que queramos al inicio de una forma cómoda. Para añadir comandos al inicio, recordemos que debemos poner una “&” al final.

sudo cp dwm-start /usr/bin

Y ahora, creamos el lanzador. Abrimos otra vez el editor, y copiamos esto:

[Desktop Entry]
Encoding=UTF-8
Name=Dwm
Comment=Dwm
Exec=dwm-start
Type=XSession

Cerramos, y lo guardamos en /usr/share/xsessions/ como dwm.desktop. Desde nuestro gestor de sesiones (Ya sea Slim, LightDM, etc…) podremos acceder a DWM.
Como nota, podemos instalarlo desde repositorio con un simple

sudo apt-get install dwm

Pero (Siempre hay un pero) esto no nos permitirá hacer ningún tipo de configuración, con lo que sólo servirá para darle un vistacillo por encima. Es una opción, pero… Ñe… es como quitarle la esencia.

Ya me diréis que os parece, en la siguiente hablaré de como dejarlo más bonito y eficaz.

2017-02-10-123630_1920x1080_scrot

Anuncios

2 comentarios en “INSTALAR Y CONFIGURAR DWM (1)

  1. Pingback: INSTALAR Y CONFIGURAR DWM (2) |

  2. Pingback: Rofi |

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s