DWM сверх легкий, сверх быстрый оконный менеджер

Dynamic Window Manager - Динамический Менеджер Окон

DWM сверх легкий оконный менеджер, в нем нет привычных заголовков окна, кнопочек закрытия, сворачивания, разворачивания окон, оформления окон, всяких там красиво выпадающих меню, иконок разноцветных, все это ему не нужно. Большая часть функций, происходит с использованием клавиатуры, все, что он делает -управляет окнами, поэтому DWM еще и помимо сверх легкого менеджера, сверх быстрый, его функционал сам по себе, дисциплинирует пользователя, прививая тем самым, что то вроде хороших манер, проникшись однажды, Вы понимаете, все остальное, что было в других менеджерах, скорее отвлекает, чем помогает в работе, вынуждая своим раздутым функционалом, делать много лишних тело движений. Безусловно, было бы не правильно, да и не объективно сравнивать DWM, например с такими гигантами как KDE и GNOME, эти представители оконного мира,уже давно, предлагают не только управление окнами,но и много другое, тем самым занимая все больше и больше не только пользовательского пространства в окружении рабочего стола, но и места на жестком диске, в оперативной памяти, неистово пожирая системные ресурсы, благо современные машины позволяют это делать, тем кто всей душей любит выше указанных представителей и им подобных. Все что делает DWM, управляет окнами, справляется он со своей задачей на 5+, по пяти бальной шкале.

Внешне DWM выглядит ровно так- как выглядят запущенные программы, которые в свою очередь занимают все рабочее пространство окна, вверху окна есть только небольшая строка состояния, где в левом углу расположены теги []{.менеджерах .других .в .столами .рабочими .с .аналогии .по} они пронумерованы, переключаться между тегами можно используя управляемые клавиши, по умолчанию это Alt+N где N номер/имя тега от 1 до 9, Alt+Tab переключает с активного тега на предыдущий тег, следом идет расположение окон, количество окон в теге, заголовок активного окна.

dwm_m.gif

По умолчанию DWM поддерживает три режима расположения окон, плиточный []= для переключения в этот режим, по умолчанию клавиши Alt+T, монокль []{lang=“M”} вместо M будет число окон- клавиши Alt+M и плавающий ><> Alt+F. Все расположения могут быть применены динамически, оптимизируя окружающую среду.

dwm_plitka_m.gif

В плиточном расположении, окна группируются в две управляемые области, мастер и укладка. Основная область мастер, содержит окно которое в настоящее время Вам нужно, тогда как область укладки,содержит все остальные окна. По умолчанию используется плиточный режим. Если открыто одно окно, оно занимает всю область пользовательского пространства, добавив новое приложение оно занимает область мастер в левой части окна, само же окно разбивается на две колонки, предыдущее приложение переходит в область укладки []{.окна .часть .правая} . Изменять размер областей можно только по ширине, управляющими клавишами Alt+H и Alt+L. В правом столбце, в области укладки будут размещаться остальные открытые окна перемещенные из области мастер, пространство в этой области делится вертикально,поровну между всеми приложениями. Перемещать предыдущее приложение из области укладки в область мастер и соответственно приложение из области мастер в область укладки,меняя их расположения местами можно управляющими клавишами Alt+Enter. Ввод Alt+Space для активного окна изменит его режим расположения на плавающий, позволяя этому окну нарушать плиточный режим расположения остальных окон. В этом режиме, можно использовать мышь для перемещения и изменения размеров окна, удерживая Alt и левую кнопку мыши, позволяет перемещать окно, Alt и правая кнопка мыши позволяет изменять размер окна.

dwm_monokl_m.gif

Нажав Alt+M Вы переключите режим расположение окон- монокль, активное окно займет все рабочее пространство и перекроет все другие открытые окна, запустив новое приложение оно перекроет предыдущие. В независимости от режима расположения окон, с помощью клавиш Alt+J, Alt+K, Вы свободно сможете переключаться между окнами делая окна активными по очереди. Если это режим расположения монокль,то одно окно будет сменять другое, если плиточный режим, то переключится фокус с одного окна на другое, в плавающем режиме все так же, окна будут активными по порядку.

Для перемещения окон между тегами, с одного тега на другой, используйте клавиши Alt+Shift+N где N номер тега в который Вы хотите перенести окно, для того что бы отобразить окно на всех тегах нажмите Alt+Shift+0 и снова Alt+Shift+N где номер тега, что бы отменить действие размещение на всех тегах этого окна, окно будет перемещено в тег N.

Для того что бы запустить консоль, нажмите Alt+Shift+Enter []{.пожелаете .если .консоль, .другую .любую .указать .сможете .Вы .дальнейшем .в .поправимо, .это .uxterm, .умолчанию .по} , Alt+P запустит dmenu для запуска приложений которые Вы будете использовать []{.желаемому .к .приближая .сокращается .приложений .список .набора .мере .по .вам, .я .скажу .вещь .удобная .очень} , только его надо предварительно установить иначе придется запускать приложения из консоли.

Для того что бы убить приложения Alt+Shift+C
Что бы спрятать строку состояния Alt+B
Что бы завершить работу DWM Alt+Shift+Q

В DWM есть ограничения о которых желательно помнить, если вы находитесь в одном теге с режимом расположения окон плитка или монокль, то переключившись на другой тег, режим расположения будет применен к тегу на который Вы переключились,что бы этого не случилось, нужно поставить режим плавающих окон и только тогда переключатся на другой тег, тогда окна останутся в том виде в каком они находились.[]{.“pertag”:http://dwm.suckless.org/patches/pertag .патча .применения .помощью .с .поправимо .Это}

Для этого cоздаем локальный оверлей:

mkdir -p /var/lib/layman/local/{x11-wm/dwm/files,profiles}
echo “local” > /var/lib/layman/local/profiles/repo_name
echo “PORTDIR_OVERLAY=\”\${PORTDIR_OVERLAY} /var/lib/layman/local\"" >> /etc/make.conf

Скидываем туда файлы из основного дерева portage

cp /usr/portage/x11-wm/dwm/dwm-6.0.ebuild /var/lib/layman/local/x11-wm/dwm/dwm-6.0-r1.ebuild

Версия указана на момент последней правки статьи

cp /usr/portage/x11-wm/dwm/files/* /var/lib/layman/local/x11-wm/dwm/files/

Скачиваем патч и сохраняем его в директорию /var/lib/layman/local/x11-wm/dwm/files/:

wget -P /var/lib/layman/local/x11-wm/dwm/files/ http://dwm.suckless.org/patches/dwm-6.0-pertag.diff

Редактируем ebuild:

/var/lib/layman/local/x11-wm/dwm/dwm-6.0-r1.ebuild

и добавляем в него следующие строки:
eutils к уже существующей переменной inherit

inherit eutils

и в значение существующей переменной src_prepare() добавим:

epatch “${FILESDIR}”/${P}-pertag.diff

Сохраняем и создаем манифест:

ebuild /var/lib/layman/local/x11-wm/dwm/dwm-6.0-r1.ebuild digest

Осталось пересобрать, возможно потребуется пакет предварительно размаскировать если воспользовались патчем:

emerge dwm --autounmask-write

Установка

Установка DWM и DMENU процесс крайне быстрый, установите USE флаг savedconfig, тогда Вы сможете применить изменения внесенные в настройки конфигурационного файла, это еще одна из особенностей DWM, после внесения изменений его нужно заново компилировать []{.минуты .меньше .занимает .безболезненная, .и .быстрая .крайне .процедура .надо, .не .пугаться} :

emerge dwm dmenu

После установки надо создать в пользовательской директории файл для запуска DWM ~/.xinitrc

touche ~/.xinitrc

Для вывода дополнительной информации в строке состояния, нужно добавить приблизительно следующее, здесь Вы сами для себя определяете что хотите, температуру,частоту процессора,время и дату, состояние сети, состояния заряда батареи, запуск приложений и т.д. .

Пример:

#!/bin/sh
exec xscreensaver &
exec urxvt &
exec hsetroot -fill /home/USER/Images/wallpapers.png &
exec /usr/bin/unclutter &

while true; do
    xsetroot -name "$(acpi -bt |awk -vORS=' ' ' /remaining/ {print($4$5)} /Thermal/ { print $4 "°" $6}' |sed -e 's/\.0//g') $(wicd-cli -dy |awk -vORS=' ' '/Essid:/ {print($1$2)} /Quality:/ {print($2)}') Звук:$(amixer -c 0 sget Master |awk '/Mono:/ {print($6$4)}') `skb 1` $(date '+%a %e %b %R')"
    sleep 1;
done &

exec dwm

В примере выше используется skb простой индикатор раскладки клавиатуры из оверлея stuff.

Или укажите то, что предлагается в конце работы emerge, после установки DWM:

while true
do
xsetroot -name “`date` `uptime | sed ‘s/.*,//’`”
sleep 1s
done &
exec dwm

Настройка

DWM использует шрифты из xorg.conf указанные в Section “Files”. Для нормального отображения кириллицы/нужного вам шрифта, необходимо указать пути к шрифтам в файле /etc/X11/xorg.conf. Для шрифта terminus указываем путь FontPath “/usr/share/fonts/terminus”.
Пример:

Section “Files”
FontPath “/usr/share/fonts/corefonts”
FontPath “/usr/share/fonts/misc”
FontPath “/usr/share/fonts/droid”
FontPath “/usr/share/fonts/terminus”
EndSection

Далее, к требуемым шрифтам, по аналогии, и не забудьте собрать пакет media-fonts/terminus-font с USE флагом X, возможно потребуется указать дополнительные флаги. Для подбора подходящего Вам шрифта используйте программу xfontsel, установить ее можно как и все прочии программы в Calculate, используя emerge.

emerge xfontsel

запуск программы:

xfontsel

Файл конфигурации DWM /etc/portage/savedconfig/x11-wm/dwm-6.0

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

/* appearance */
static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
static const char normbordercolor[] = "#444444";
static const char normbgcolor[]     = "#222222";
static const char normfgcolor[]     = "#bbbbbb";
static const char selbordercolor[]  = "#005577";
static const char selbgcolor[]      = "#222222";
static const char selfgcolor[]      = "#005577";
static const unsigned int borderpx  = 1;        /* border pixel of windows */
static const unsigned int snap      = 32;       /* snap pixel */
static const Bool showbar           = True;     /* False means no bar */
static const Bool topbar            = True;     /* False 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 */
    { "MPlayer",  NULL,    NULL,      0,            True,        -1 },
    { "Skype",    NULL,    NULL,      0,            True,        -1 },
    { "Gimp",     NULL,    NULL,      0,            True,        -1 },
    { "Gpicview", NULL,    NULL,      0,            False,       -1 },
    { "Firefox",  NULL,    NULL,      0,            False,       -1 },
    { "Spacefm",  NULL,    NULL,      0,            False,       -1 },
    { "URxvt",    NULL,    NULL,      0,            False,       -1 },
    { "Dwb",      NULL,    NULL,      1 << 1,       False,       -1 },
    { NULL,       NULL,    "mc",      0,            False,       -1 },
    { NULL,       NULL,    "irssi",   1 << 3,       False,       -1 },
    { NULL,       NULL,    "mcabber", 1 << 2,       False,       -1 },
    { "Zathura",  NULL,    NULL,      1 << 5,       False,       -1 },
    { NULL,       NULL,    "cmus",    1 << 6,       False,       -1 },
    { NULL,       NULL,    "newsbeuter",   1 << 7,       False,       -1 },
    { NULL,       NULL,    "rtorrent",   1 << 8,       False,       -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 Bool resizehints = True; /* True 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 Mod4Mask
#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/bash", "-c", cmd, NULL } }

/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[]  = { "urxvt", NULL };
static const char *dwbcmd[]  = { "dwb", NULL };
static const char *irssicmd[]  = { "urxvt", "-title", "irssi", "-e", "irssi",  NULL };
static const char *mccmd[]  = { "urxvt", "-title", "mc", "-e", "mc",  NULL };
static const char *mcabbercmd[]  = { "urxvt", "-title", "mcabber", "-e", "mcabber",  NULL };
static const char *zathuracmd[]  = { "zathura", NULL };
static const char *cmuscmd[]  = { "urxvt", "-title", "cmus", "-e", "cmus",  NULL };
static const char *newsbeutercmd[]  = { "urxvt", "-title", "newsbeuter", "-e", "newsbeuter",  NULL };
static const char *rtorrentcmd[]  = { "urxvt", "-title", "rtorrent", "-e", "rtorrent",  NULL };

static Key keys[] = {
    /* modifier                     key        function        argument */
    { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
    { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
    { MODKEY|ShiftMask,             XK_d,      spawn,          {.v = dwbcmd } },
    { MODKEY|ShiftMask,             XK_i,      spawn,          {.v = irssicmd } },
    { MODKEY|ShiftMask,             XK_f,      spawn,          {.v = mccmd } },
    { MODKEY|ShiftMask,             XK_m,      spawn,          {.v = mcabbercmd } },
    { MODKEY|ShiftMask,             XK_z,      spawn,          {.v = zathuracmd } },
    { MODKEY|ShiftMask,             XK_a,      spawn,          {.v = cmuscmd } },
    { MODKEY|ShiftMask,             XK_n,      spawn,          {.v = newsbeutercmd } },
    { MODKEY|ShiftMask,             XK_r,      spawn,          {.v = rtorrentcmd } },
    { 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} },
};

В завершение скажу лишь о своем впечатлении, DWM стоит того, что бы им пользоваться, это замечательный менеджер, дает возможность сфокусировать внимания на приложениях которыми Вы пользуетесь, не думая об окружении рабочего стола и заморочках связанных с его настройкой, на первый взгляд может показаться, что в настройке, DWM еще более замороченный, возможно, возможно потребуется время на освоение и привыкание, но в Linux все ключевые приложения требуют освоения, да и разве маленькая программка в которой всего лишь 2000 тысячи строк по заявлению авторов, может быть более замороченной чем менеджеры у которых на борту по зависимостям десятки приложений, огромная туча пакетов, пойди разберись что к чему. Спорить не буду, доказывать и убеждать тоже, кто проникся и заинтересовался желаю успехов, кого не зацепило, уверен у Вас есть приложение доставляющие Вам удовольствие и удобство в работе.
Сайт проекта: http://dwm.suckless.org/ а также на русской Gentoo вики есть достаточно подробное описание.

Рекомендуемые приложения:

dwb zathura mcabber cmus newsbeuter rtorrent irssi или weechat sxiv turses

пардон, может поможете с одним траблом:
есть н-ное количество консольных приложений - например mutt или newsbeuter
запускается просто
static const char *newscmd[] = { "urxvt", "-bg", "black", "-fg", "white", "-e", "newsbeuter", "-r", NULL };
но вопрос - как привязать его к конкретному тегу?

xprop выводит
WM_CLASS(STRING) = "urxvt", "URxvt"
WM_ICON_NAME(STRING) = "userhost:~"@
что не подходит, ибо терминал привязан к отдельному тегу, а по WM_ICON_NAME в отличие от , например, емакса собранного с флагом -Х, не привяжешь

Константин А писал(а):

пардон, может поможете с одним траблом:
есть н-ное количество консольных приложений - например mutt или newsbeuter
запускается просто
static const char *newscmd[] = { "urxvt", "-bg", "black", "-fg", "white", "-e", "newsbeuter", "-r", NULL };
но вопрос - как привязать его к конкретному тегу?

xprop выводит
WM_CLASS(STRING) = "urxvt", "URxvt"
WM_ICON_NAME(STRING) = "userhost:~"@
что не подходит, ибо терминал привязан к отдельному тегу, а по WM_ICON_NAME в отличие от , например, емакса собранного с флагом -Х, не привяжешь

Вот так глубоко не копал… а табы urxvt использовать не пробовал, меня устраивало, cmus, mc, weechat, mcabber и все в табах… вот есть идея для ориентира - http://www.gentoo.ru/node/21774 только не спрашивай как это реализовать c urxvt, ибо не пробовал…

Упс! а куда делись все коменты, кто скажет?

вот так всегда, спросишь что-нибудь, и через какое-то небольшое время сам прекрасно догоняешь, как это сделать )))

как оказалось - ларчик открывался не просто, а очень просто - запускать urxvt с ключом -name <нужное_имя>, а его уже прописывать в title: примерно так

static const char *newscmd[] = { "urxvt", "-bg", "black", "-fg", "white", "-name", "newsbeuter", "-e", "newsbeuter", "-r", NULL }

и правило для него
{ NULL, NULL, "newsbeuter", 1 << 3, False, -1 },

Aleksey Vasilyevich писал(а):

Упс! а куда делись все коменты, кто скажет?

пардон, может сие от того, что я изначальную мессагу раза три правил?

Здорово! думаю пригодится, отличное дополнение… кстати не пробовал на версии dwm 6.0 патч, что бы запоминал раскладку клавиатуры, я его применял на 5.9 http://www.calculate-linux.ru/blogs/show/322

А по поводу коментов, это я перепутал с другой веткой, все смешалось в голове, просто применялось то все на одном компе, а писалось в разных постах :smiley:

статью в блоге видел, но патч пока не пробовал , так как за ~полторы недели активного пользования dwm проблемы не с этим не возникало. честно говоря - если б не статья , то я бы и не заметил что у dwm с этим трабла
offtop : там еще в portege вкралась очепятка

[]{.Америку .открываю .заново .если .пардон .заранее}

x11-misc/unclutter - вещь, которой мне люто-бешено не хватало в dwm.
Что делает - скрывает курсор, если мышь не трогали н-ное количество секунд

Константин А wrote:

[]{.Америку .открываю .заново .если .пардон .заранее}

Нет не америку :wink: спс, сейчас установлю, поглядеть…

Установил, но продолжаю рефлексировать и тяну курсор всторону с глаз долой, по привычке (это диагноз, подумал Штирлиц):smiley:

ну не знаю я за полдня привык. м.б. время подходящее подобрать - имхо 1 секунда самое оно