Awesome – гибкоконфигурирумый динамический тайлинговый оконный менеджер. Очень легкий и расширяемый за счет использования языка программирования Lua. Awesome нацелен на опытных пользователей, разработчиков и людей, желающих использовать гибкий инструмент в повседневной работе.

Лучший оконный менеджер тот, которого не видно

Распространено мнение, что тайлинговые оконные менеджеры- для больших экранов, хочется заметить, что это не так, тайлинговый оконный менеджер отлично себя чувствует на нетбуке, где, чаще всего, работать приходится без мыши, а в работе с клавиатуры тайлинговым менеджерам нет равных. Естественно ни о каком толковом тайлинге окон на нэтбуке нельзя говорить, на всех тэгах установлена максимизация окна приложения.

Установка

AwesomeWM

дополнения для AwesomeWM

Перед установкой настоятельно рекомендуется ознакомиться с языком программирования Lua, так как весь процесс настройки будет происходить с использованием этого языка.

 sudo apt-get install awesome awesome-extra

После этого при логине в меню выбора сессии можно указать Awesome и начать знакомство с этим удивительным оконным менеджером (на рисунке ниже видно, что данный оконный менеджер полностью оправдывает свое название). Как и во всех тайлинговых оконных менеджерах окна (клиенты) занимают все свободное пространство рабочего стола.

Настройки клавиатуры по умолчанию
mod4- по умолчанию клавиша Windows
Команда Сочетание
Вызов терминала mod4+Enter
Вызов меню mod4+w
Запуск приложения mod4+r
Перезапуск Awesome mod4+Control+r
Выход Awesome mod4+Shift+q

Больше см. man awesome

По умолчанию Awesome использует стандартные файлы конфигурации, поэтому для применения изменений после установки необходимо скопировать стандартный файл конфигурации, в папку ~/.config/awesome. В последствии, если Вы нарушите работоспособность своего конфигурационного файла, оконный менеджер запустится с настройками по умолчанию.

 cp /etc/xdg/awesome/rc.lua ~/.config/awesome/

Настройка

Перед любым изменением конфигурационного файла рекомедуется сохранить копию исходного. При возникновении ошибок в синтаксисе Awesome загрузится в стандартной или частично-стандартной конфигурации. Для проверки кода файла rc.lua можно выполнить
awesome -k ~/.config/awesome/rc.lua

Но данная команда проверяет только синтаксис, поэтому, при не правильной адресации и многих других ошибках она не поможет.

Если вы не сильны в Lua и не очень хотите его подробно изучать, то в любом месте конфигурационного файла можно указать выполнение собственного скрипта, написанного на вашем любимом языке. Например так:

-- Create a textclock widget
mytextclock = awful.widget.textclock({ align = "right" })
mytextclock:buttons(awful.util.table.join(       
awful.button({ }, 1, function ()
awful.util.spawn_with_shell("/home/<имя_пользователя>/bin/dairy.sh") end)
        ))

Данный код будет при нажатии на виджет часов на панели awesome вызывать скрипт /home/<имя_пользователя>/bin/dairy.sh.

Раскладка клавиатуры

При загрузке в голый AwesomeWM (без сессии GNOME) перестает работать переключение раскладки клавиатуры1)) Для настройки необходимо добавить в автозапуск команду

setxkbmap -layout 'us,ru' -variant ',winkeys,winkeys' -option grp:caps_toggle -option grp_led:caps -option terminate:ctrl_alt_bksp

Ниже описан способ добавления комады в автозагрузку awesome и способ отображения раскладки на панели

Обновление https://awesomewm.org/doc/api/documentation/89-NEWS.md.html У Awesome теперь есть встроенная поддержка обнаружения и настройки раскладки клавиатуры. Использование setxkbmap больше не требуется. Также добавлен виджет для просмотра текущей раскладки.

Тэги

Отличительная особенность Awesome (и большинства тайлинговых оконных менеджеров)- система тэгов, вместо привычных виртуальных рабочих столов. Система тэгов более гибка и конфигуриуема. Например можно назначит несколько тэгов для одного приложения (клиента) или настроить отображение приложений с несколькими тэгами одновременно.

Настройки клавиатуры по умолчанию
mod4- по умолчанию клавиша Windows
Команда Сочетание
Переключиться на следующий тэг mod4+Right
Переключиться на предыдущий тэг mod4+left
Переключиться на тэг по номеру (1-9) mod4+(1-9)
Включить/выключить отображение тэга по номеру (1-9) mod4+Control+(1-9)
Пометить приложение тэгом по номеру (1-9) mod4+Shift+(1-9)
Пометить/снять пометку приложения тэгом по номеру (1-9) mod4+Shift+Control+(1-9)

Больше см. man awesome

Настройка тэгов и схем (layouts).

Тэги и схемы расположения клиентов- основное с чем придется работать повседневно при использовании оконного менеджера Awesome, поэтому целесообразно уделить повышенное внимание их настройке.

Кусок кода rc.lua, отвечающий за работу схем расположения клинетов:

layouts =
{
    awful.layout.suit.floating,
    awful.layout.suit.tile,
    awful.layout.suit.tile.left,
    awful.layout.suit.tile.bottom,
    awful.layout.suit.tile.top,
    awful.layout.suit.fair,
    awful.layout.suit.fair.horizontal,
    awful.layout.suit.spiral,
    awful.layout.suit.spiral.dwindle,
    awful.layout.suit.max,
    awful.layout.suit.max.fullscreen,
    awful.layout.suit.magnifier
}

Здесь наглядно показана работа основного инструмента языка Lua- таблица. Создается таблица с именем layouts и в ячейки [1]-[9] записываются различные значения схем.

Настройка схем расположения клиентов сводится к исключению (комментированию) не используемых.

При комментировании одной из строк изменяется нумерация ячеек в формируемой таблице layouts, это необходимо учитывать и при редактировании следить за назначением схемы для тэгов.

Кусок кода rc.lua, отвечающий за формирование списка тэгов и отображение их на экране:

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
end
-- }}}

Данный код формирует для каждого экрана (s) 9 тэгов с именами от 1 до 9 и выставляет для всех схему, записанную в первой ячейке таблицы layout (по умолчанию float).

Настройка тэгов, как правило, заключается в:

  • Изменении имен тэгов;
  • Указание для тэгов определенных схем тайлинга;
  • Настройка выбранной схемы для определенного тэга.

Как правило при настройке тэгов в именах вместо цифр используют графические символы или буквы греческого алфавита. Нецелесообразно в имени тэга использовать слова (www, office, и т.д.), потому что они будут расходовать ценное место на панели, которое можно занять полезными виджетами, а назначение тэгов в процессе использования закрепятся в памяти сами собой.

Для настройки тэгов, введем дополнительную таблицу с именем tags, в которой будут две ячейки, представляющие собой так же таблицы, это names и layout, в которые, в свою очередь, уже будут записываться значения для каждого тэга.

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {
names = {"⠐", "⠡", "⠪", "⠵", "⠻", "⠿",},
layout = {layouts[2], layouts[2], layouts[4], layouts[2], layouts[4], layouts[2]}
}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag(tags.names, s, tags.layout)
end
-- }}}

Так же вместо символов в именах тэгов можно использовать любые иконки, для этого код будет выглядеть следующим образом:

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {
names = {"","","","","",""},
layout = {layouts[2], layouts[2], layouts[4], layouts[2], layouts[4], layouts[2]}
}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag(tags.names, s, tags.layout)
    awful.tag.seticon(beautiful.homeicon, tags[s][1])
    awful.tag.seticon(beautiful.wwwicon, tags[s][2])    
    awful.tag.seticon(beautiful.officeicon, tags[s][3])
    awful.tag.seticon(beautiful.chaticon, tags[s][4])
    awful.tag.seticon(beautiful.wineicon, tags[s][5])
    awful.tag.seticon(beautiful.mediaicon, tags[s][6])
end
-- }}}

в строке awful.tag.seticon(beautiful.homeicon, tags[s][1]) происходит обращение к файлу иконки в формате beautiful.homeicon, это возможно при указании пути к иконке в файле темы awesome theme.lua для редактирования необходимо скопировать его в домашний каталог из стандартной папки:

mkdir ~/.config/awesome/themes
cp /usr/share/awesome/themes/default/* ~/.config/awesome/themes

И создать в нем иконку с именем homeicon, указав путь к файлу изображения:

--MyIcons
theme.mediaicon = "/usr/share/icons/Faenza-Dark/status/16/rhythmbox-panel.png"
theme.chaticon = "/usr/share/icons/Faenza-Dark/status/16/user-available-panel.png"
theme.homeicon = "/usr/share/icons/Faenza-Darkest/actions/16/go-home.png"
theme.wineicon = "/usr/share/icons/Faenza-Darkest/actions/16/window-new.png"
theme.officeicon = "/usr/share/icons/Faenza-Darkest/actions/16/gtk-edit.png"
theme.wwwicon = "/usr/share/icons/Faenza-Darker/actions/16/find.png"
--EndMyIcons

Одновременно с изменением имени в примерах, приведенных выше, для каждого тэга указывается схема расположения клиентов, в ячейка layout таблицы tags. В квадратных скобках указывается номер ячейки таблицы layouts.

Для настройки схемы расположения клиентов внутри определенного тэга кусок кода Tags должен выглядить следующим образом:

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {
names = {"⠐", "⠡", "⠪", "⠵", "⠻", "⠿",},
layout = {layouts[2], layouts[2], layouts[4], layouts[2], layouts[4], layouts[2]}
}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag(tags.names, s, tags.layout)
	awful.tag.setncol(2, tags[s][4])
	awful.tag.setproperty(tags[s][4], "mwfact", 0.20)
end
-- }}}

Здесь нас интересуют строки с функциями awful.tag.setncol и awful.tag.setproperty, первая функция устанавливает число колонок стэк-зоны в значение 2 для четвертого тэга, вторая функция устанавливает значение ширины мастер-зоны -20% от ширины экрана.

Понятия «стэк-зона» и «мастер-зона» применяются к типу схемы tile и означает:
  • мастер-зона- область схемы tile куда по умолчанию открываются новые клиенты;
  • стек-зона- область схемы tile куда сдвигаются уже открытые клиенты при запуске нового.

Полный перечень доступных функций приведен в официальном описании API(eng).

Использование виджетов

Ещё одна особенность Awesome- гибкоконфигурируемые виджеты, позволяющие отказаться от использования conky.

Blingbling

Замечательные виджеты blingbling. Основное отличие- ориентированность на графику.

Установка

Для корректной работы blingbling необходимы пакеты liblua5.1-oocairo-1.4-1.2 и liblua5.1-oocairo-dev 1.4-1.2

На 09.07.2012 в репозиториях ubuntu лежат пакеты liblua5.1-oocairo-1.4-1.1 и liblua5.1-oocairo-dev 1.4-1.1 и они не пригодны для работы с blingbling из за бага их необходимо скачать и установить из репозитория debian-sid

Установка blingbling из git:

cd ~/.config/awesome
git clone git://github.com/cedlemo/blingbling.git

Использование

В начало файла rc.lua необходимо добавить

require("blingbling")

Описание конфигурации виджетов приведено в файле

~/.config/awesome/blingbling/README

Регулятор громкости

Для добавления регулятора громкости необходимо выполнить следующие шаги:

  1. в файл rc.lua добавляем описание виджета:
    -- Volume widget
    volume_label = widget ({ type = "textbox" })
    volume_label.text = "♫"
    my_volume=blingbling.volume.new()
    my_volume:set_height(18)
    my_volume:set_v_margin(4)
    my_volume:set_width(20)
    my_volume:update_master()
    my_volume:set_master_control()
    my_volume:set_bar(true)
    my_volume:set_background_graph_color("#444444")--beautiful.bg_focus)
    my_volume:set_graph_color(beautiful.motive)--beautiful.fg_normal)

  2. добавляем на wibox созданный виджет:

        mywibox[s].widgets = {
            {
                mylauncher,
                mytaglist[s],
                mypromptbox[s],
                layout = awful.widget.layout.horizontal.leftright
            },
            system_button, separator,
            mytextclock, separator,
            kbdwidget, separator,
            my_volume.widget,volume_label,separator, -- <<-- добавленный виджет и разделитель
            uptime, separator,
            cpuwidget, separator,
            cputempwidget, separator,
            memwidget,separator,
            s == 1 and mysystray or nil,
            mytasklist[s],
            layout = awful.widget.layout.horizontal.rightleft
        }

  3. В результате, если крутить колесо мыши над виджетом происходит регулировка громкости, если нажать левой кнопкой- включение/выключение звука, а выглядеть это будет так:

Проблемы

У меня, а как показал поиск и ещё у нескольких людей на ноутбуках HP Pavilion, наблюдается проблема- при попытке приглушить звук через команду amixer Master toggle, которая используется и в упомянутом выше виджете, звук успешно выключается, но после этого не включается обратно. Не знаю в чем причина такого поведения, но заметил, что если после этого в alsamixer переключать хаотично все каналы mute/unmute- кнопкой «M», то звук включится обратно, поэтому есть довольно тривиальное решение этой проблемы- включать\выключать приглушение звука скриптом, вот он (можно скачать щелкнув по имени файла):

sndfx.sh
#!/bin/bash
    if amixer -c 0 get Master | grep -q off
then
    amixer set Master unmute
    amixer set Speaker unmute
    amixer set Front unmute
else
    amixer set Master mute
fi
При необходимости удалите лишние строчки или поправьте название каналов, взяв их из alsamixer

Проверяем работоспособность:

chmod +x /путь/к/скрипту/sndfx.sh
/путь/к/скрипту/sndfx.sh #после этой команды звук должен отключиться
/путь/к/скрипту/sndfx.sh #после этой команды- включиться

Если все работает нормально, правим управляющий файл виджета volume из blingbling:

 gedit ~/.config/awesome/blingbling/volume.lua

ищем и исправляем следующий кусок файла:

local function set_master_control(v_graph)
    v_graph.widget:buttons(awful.util.table.join(
    awful.button({ }, 1, function()
--      set_master("toggle")
    awful.util.spawn("/путь/к/скрипту/sndfx.sh")
    end),
    awful.button({ }, 5, function()
      set_master("5%-") --<<-- здесь можно изменить шаг регулировки громкости
    end),
    awful.button({ }, 4, function()
      set_master("5%+") --<<-- здесь можно изменить шаг регулировки громкости
    end)))
end

Другой способ решения этой же проблемы. В файле

 gedit ~/.config/awesome/blingbling/volume.lua

в функции set_master исправляем

local function set_master(parameters)
    -- local cmd = "amixer --quiet set Master " ..parameters
    local cmd = "amixer -D pulse --quiet set Master 1+ " ..parameters
    local f=io.popen(cmd)
    f:close()
end

Погода

Виджет найден здесь в крайне заброшенном состоянии и реабилитирован. Данный виджет работает от Яндекс.Погода, снабжен набором иконок.

Установка

  1. Необходимо скачать архив и распаковать его содержимое в папку ~/.config/awesome/, так что бы получилось следующее дерево каталогов:

    ├── awesome
       ├── awful
       ├── debian
       ├── rc.lua
       ├── README
       ├── themes
       ├── vicious
       ├── weather_icons
       └── weather.lua
  2. В начале вашего rc.lua необходимо добавить строку:

    require("weather")
  3. После этого необходимо создать text или image- виджет:

    weatherwidget = widget({ type = "textbox" })
    weather.addWeather(weatherwidget, "moscow", 3600)

    где:

    moscow- получаем перейдя по ссылке Яндекс.Погода и выбрав на странице свой город, искомое значение параметра будет в адресной строке:

    http://pogoda.yandex.ru/<параметр_для_вставки>/?ncrnd=1423

    (по умолчанию данный параметр- moscow);

    3600-время обновления в секундах (по умолчанию- 907)

  4. Поместить виджет в любое удобное место wibox.

Использование

При наведении на виджет на панели будет отображаться всплывающее уведомление awesome с иконкой и основной информацией. Можно установить сколько угодно виджетов на панель, но нельзя установить несколько городов в один виджет. На скриншоте на панель добавлено два виджета одновременно: один- imagebox, второй- textbox.

Часы

По умолчанию в awesome на панель добавлены часы (mytextclock). При наведении красоты вам захочется изменить формат отображения и добавить в них календарь.

Формат вывода

В вашем файле rc.lua редактируем строку инициализации виджета textclock, дописывая параметры:

mytextclock = awful.widget.textclock({ align = "right" }, "%a %d %b, %H:%M")

здесь:

  • %a– день недели;
  • %d– дата;
  • %b– месяц;
  • %H– часы;
  • %M– минуты.

полный перечень параметров можно посмотреть в man date

Учтите, что по умолчанию awesome обновляет время раз в минуту, поэтому если вы добавите к формату textclock секунды, вам нужно будет добавить параметр частоты обновления, строка из примера примет вид:
mytextclock = awful.widget.textclock({ align = "right" }, "%a %d %b, %H:%M", 1)

Локализация

Добавив к часам дату и день недели, вы обнаружите их не локализованными. Это нормально, потому что локализация системы и локализация в языке Lua- разные вещи. Конфигурационный файл виджета textclock хранится по пути

/usr/share/awesome/lib/awful/widget/textclock.lua

Хорошим тоном является копирование дефолтных конфигурационных файлов в домашнюю папку, что бы в случае возникновения проблем система могла работать на дефолтной конфигурации, поэтому копируем:

mkdir -p ~/.config/awesome/awful/widget
cp /usr/share/awesome/lib/awful/widget/textclock.lua ~/.config/awesome/awful/widget/textclock.lua

Для корректного отображения необходимо в файл

~/.config/awesome/awful/widget/textclock.lua

перед командой запроса даты добавить команду установки локализаци. Файл textclock.lua примет вид:

textclock.lua
---------------------------------------------------------------------------
-- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2009 Julien Danjou
-- @release v3.4.11
---------------------------------------------------------------------------
 
local setmetatable = setmetatable
local os = os
local capi = { widget = widget,
               timer = timer }
 
--- Text clock widget.
module("awful.widget.textclock")
 
--- Create a textclock widget. It draws the time it is in a textbox.
-- @param args Standard arguments for textbox widget.
-- @param format The time format. Default is " %a %b %d, %H:%M ".
-- @param timeout How often update the time. Default is 60.
-- @return A textbox widget.
function new(args, format, timeout)
    local args = args or {}
    local format = format or "%a %d %b %H:%M"
    local timeout = timeout or 60
    args.type = "textbox"
    local w = capi.widget(args)
    local timer = capi.timer { timeout = timeout }
    os.setlocale("ru_RU.utf8")
    w.text = os.date(format)
    timer:add_signal("timeout", function() w.text = os.date(format) end)
    timer:start()
    return w
end
 
setmetatable(_M, { __call = function(_, ...) return new(...) end })

Календарь

Для того, что бы при наведении указателя мыши на часы появлялся простой календарик необходимо подключить дополнительный модуль calendar2, код взят из вики awesome и немного исправлен2)

calendar2.lua
-- original code made by Bzed and published on http://awesome.naquadah.org/wiki/Calendar_widget
-- modified by Marc Dequènes (Duck) <Duck@DuckCorp.org> (2009-12-29), under the same licence,
-- and with the following changes:
--   + transformed to module
--   + the current day formating is customizable
 
local string = string
--local print = print
local tostring = tostring
local os = os
local capi = {
    mouse = mouse,
    screen = screen
}
local awful = require("awful")
local naughty = require("naughty")
module("calendar2")
 
local calendar = {}
local current_day_format = "<u>%s</u>"
 
function displayMonth(month,year,weekStart)
        local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1
        local d=os.date("*t",t)
        local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7
 
        --print(mthDays .."\n" .. stDay)
        local lines = "  " --интервал перед днями неделями
		os.setlocale("ru_RU.utf8")
        for x=0,6 do
                lines = lines .. os.date("%a ",os.time{year=2006,month=1,day=x+wkSt})
        end
       lines = lines .. "\n"-- .. os.date(" %V",os.time{year=year,month=month,day=1}) --Убираем номер недели
 
        local writeLine = 1
        while writeLine < (stDay + 1) do
                lines = lines .. "    " --интервал перед первым числом, если оно не в начале недели
                writeLine = writeLine + 1
        end
 
        for d=1,mthDays do
                local x = d
                local t = os.time{year=year,month=month,day=d}
                if writeLine == 8 then
                        writeLine = 1
                        lines = lines .. "\n"-- .. os.date(" %V",t) --убираем номер недели
                end
                if os.date("%Y-%m-%d") == os.date("%Y-%m-%d", t) then
                        x = string.format(current_day_format, d)
                end
                if (#(tostring(d)) == 1) then
                        x = " " .. x --выравнивание между одно и двухзначными цифрами
                end
                lines = lines .. "  " .. x --интервал между числами
                writeLine = writeLine + 1
        end
        local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1})
		header = "          " .. header --выравниваем месяц и год по центру
        return header .. "\n" .. lines
end
 
function switchNaughtyMonth(switchMonths)
        if (#calendar < 3) then return end
        local swMonths = switchMonths or 1
        calendar[1] = calendar[1] + swMonths
        calendar[3].box.widgets[2].text = string.format('<span font_desc="%s">%s</span>', "monospace", displayMonth(calendar[1], calendar[2], 2))
end
 
function switchNaughtyGoToToday()
        if (#calendar < 3) then return end
        local swMonths = switchMonths or 1
        calendar[1] = os.date("*t").month
        calendar[2] = os.date("*t").year
       switchNaughtyMonth(0)
end
 
function addCalendarToWidget(mywidget, custom_current_day_format)
  if custom_current_day_format then current_day_format = custom_current_day_format end
 
  mywidget:add_signal('mouse::enter', function ()
        local month, year = os.date('%m'), os.date('%Y')
        calendar = { month, year,
        naughty.notify({
                text = string.format('<span font_desc="%s">%s</span>', "monospace", displayMonth(month, year, 2)),
                timeout = 0,
                hover_timeout = 0.5,
                screen = capi.mouse.screen
        })
  }
  end)
  mywidget:add_signal('mouse::leave', function () naughty.destroy(calendar[3]) end)
 
  mywidget:buttons(awful.util.table.join(
    awful.button({ }, 1, function()
        switchNaughtyMonth(-1)
    end),
    awful.button({ }, 2, switchNaughtyGoToToday),
    awful.button({ }, 3, function()
        switchNaughtyMonth(1)
    end),
    awful.button({ }, 4, function()
        switchNaughtyMonth(-1)
    end),
    awful.button({ }, 5, function()
        switchNaughtyMonth(1)
    end),
    awful.button({ 'Shift' }, 1, function()
        switchNaughtyMonth(-12)
    end),
    awful.button({ 'Shift' }, 3, function()
        switchNaughtyMonth(12)
    end),
    awful.button({ 'Shift' }, 4, function()
        switchNaughtyMonth(-12)
    end),
    awful.button({ 'Shift' }, 5, function()
        switchNaughtyMonth(12)
    end)
  ))
end

Для установки необходимо:

  1. сохранить приведенный выше файл в папку ~/.config/awesome/

  2. добавить вверху файла rc.lua строку

     require("calendar2")
  3. добавить после строки инициализации виджета часов строку вида

    calendar2.addCalendarToWidget(mytextclock, "<span color='green'>%s</span>")

Выглядит это следующим образом: нажатием левой или правой кнопкой мыши (или кручением колесика) переключаются месяцы, нажатием средней кнопки мыши- устанавливается текущий месяц.

Меню

Настройка внешнего вида

Темы

Вид GTK приложений

Ниже описаны два разных способа настройки внешнего вида приложений, вы вправе выбрать какой вам подходит больше.

lxappearance

Плюс данного способа в том, что не требуется запуск дополнительной службы и система более «чистая». Для того, что бы настраивать темы GTK, темы иконок и т.д. можно воспользоваться легким редактором внешнего вида из проекта LXDE lxappearance

sudo apt-get install lxappearance

gnome-settings-daemon

Оптимальным решением будет добавление в автозагрузку awesome службы gnome-settings-daemon, данная служба будет применять все настройки gnome-control-center включая управление питанием, назначением горячих клавиш, переключением раскладки и т.д. Единственный минус его использования- в трее появляется значок клавиатуры, но его можно легко убрать.

Вид Qt приложений

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

sudo apt-get install qt4-qtconfig

Требуемое приложение- qtconfig, после его запуска откроется окно, в котором можно будет детально настроить отображение Qt приложений, например Skype. Не забывайте сохранять изменения, при помощи комбинации Ctrl+S или через меню «Файл»-«Сохранить»

Горячие клавиши, мультимедиа кнопки

Замечательная особенность AwesomeWM- возможность «повесить» на любое ваше действие на клавиатуре/мыши любое действие системы или запуск программы3).

Кнопки управления громкостью

На большинстве современных ноутбуков имеются кнопки запуска приложений, управления воспроизведением музыки или просто управлением громкости. Для того чтобы их оживить, нужно знать их «сканкоды»- коды, которые генерируются при их нажатии. Для того что бы их узнать воспользуемся приложением xev, которое входит в состав пакета X11-utils и поставляется по умолчанию, после запуска в терминале команды xev откроется дополнительное окно, и нажмите необходимую кнопку, в терминале, если данная клавиша уже не назначена в системе и она распознается на железном уровне, появится подобный вывод:

KeyPress event, serial 41, synthetic NO, window 0x2600001,
    root 0xa6, subw 0x0, time 70181008, (-301,-183), root:(378,197),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 41, synthetic NO, window 0x2600001,
    root 0xa6, subw 0x0, time 70181015, (-301,-183), root:(378,197),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Здесь нас интересует фраза «keycode 122», 122- искомое значение.
На моём ноутбуке 121-mute, 122- уменьшение громкости и 123- увеличение. Добавляем в rc.lua следующий код:

        awful.key({}, "#121", function () awful.util.spawn("/путь/к/скрипту/sndfx.sh") end),
        awful.key({}, "#122", function () awful.util.spawn("amixer set Speaker 5%-") end),
        awful.key({}, "#123", function () awful.util.spawn("amixer set Speaker 5%+") end),

здесь вы можете увидеть, что на кнопку «mute» установлено выполнение скрипта, это связано с проблемой описанной в разделе о blingbling, скрипт выложен там же.

Работа с сессиями пользователей

Если у вас на компьютере работает несколько пользователей, то вы, работая в сессии Ubuntu, вероятно оценили удобство меню, появляющееся по нажатию на имя пользователя на панели Unity, позволяющее легко переключаться между сессиями пользователей. Хотелось бы иметь подобное меню и в AwesomeWM.

Операцию переключения пользователя обеспечивает пакет dm-tools, подробно о его применении можно почитать в справке man dm-tools. Для добавления в правый верхний угол кнопки с системным меню проделаем следующее.

  1. Добавляем в rc.lua конфигурацию меню:
    system_menu = awful.menu({ items = {
        { "Переключить пользователя", "dm-tool switch-to-greeter" },
        { "Гость", "dm-tool switch-to-guest" },
        { "Пользователь N", "dm-tool switch-to-user системное_имя_пользователя_N" },
        { "Выйти", awesome.quit },
        { "=====Awesome=====" },
        { "Руководство", terminal .. "-e man awesome" },
        { "Настройка", editor_cmd .. " " .. awesome.conffile },
        { "Перезапуск", awesome.restart },
        { "=====Система=====" },
        { "Параметры системы", "gnome-control-center" },
        { "Спящий режим", "sudo pm-hibernate" },
        { "Перезагрузка", "sudo reboot" },
        { "Выключение", "sudo shutdown" },
    },width = 250,
    })

    В данном меню предусмотрены команды управления питанием, для того, что бы эти пункты меню работали, необходимо сконфигурировать sudoers на выполнение данных команд без запроса пароля.

  2. Добавляем в файл ~/.config/awesome/themes/theme.lua иконку создаваемой кнопки меню(пример для AwOken):

    theme.system_icon = "/usr/share/icons/AwOken/clear/24x24/categories/applications-system.png"

  3. Создаем в rc.lua виджет типа «launcher» для вызова меню:

    system_button = awful.widget.launcher({ image = image(beautiful.system_icon),
                                        menu = system_menu })

  4. Добавляем созданный виджет в крайнее правое положение панели(файл rc.lua):

     mywibox[s].widgets = {
            {
                mylauncher,
                mytaglist[s],
                mypromptbox[s],
                layout = awful.widget.layout.horizontal.leftright
            },
            system_button,
            mytextclock,
            s == 1 and mysystray or nil,
            mytasklist[s],
            layout = awful.widget.layout.horizontal.rightleft
        }
Для того, что бы при переключении пользователя можно было слышать звуки «фоновых» пользователей, воспользуйтесь данным руководством

Автомонтирование внешних накопителей

Используя программу из рабочего окружения Unity можно настроить автомонтирование внешних носителей при подключении. Для этого необходимо добавить в автозагрузку демон /usr/lib/gnome-settings-daemon/gnome-fallback-mount-helper, настройки на его действия задаются в gnome-control-center(«Параметры системы» в Unity), но в сессии, отличной от Unity, пункт конфигурации этого демона убирается, поэтому для его настройки необходимо зайти в сессию Unity.

Использование с рабочим окружением (Desktop Environment)

Так как Awesome является всего лишь оконным менеджером, то после запуска сессии Awesome не будет запущено никаких служб и сервисов, что с одной стороны хорошо, с точки зрения быстродействия и легкости, а с другой стороны- не очень, с точки зрения удобства использования. В данном разделе будет рассмотрена возможность запуска сессии основных рабочих окружений с Awesome в качестве оконного менеджера.

GNOME

Запуск

Устанавливаем панель GNOME

 sudo apt-get install gnome-panel

Создаем файл сессии Gnome+AwesomeWM
/usr/share/xsessions/gnome-awesome.desktop

[Desktop Entry]
Name=Gnome with Awesome
Comment=Gnome with Awesome as window manager
TryExec=gnome-session
Exec=gnome-session --session=awesome
Type=Application

Создаем файл GNOME сессии
/usr/share/gnome-session/sessions/awesome.session

[GNOME Session]
Name=Awesome
RequiredComponents=gnome-panel;gnome-settings-daemon;
RequiredProviders=windowmanager;
DefaultProvider-windowmanager=awesome
Строку RequiredComponents можно использовать как автозагрузку, все приложения, записанные через точку с запятой выполняются при запуске сессии.

Создаем .desktop файл для Awesome
/usr/share/applications/awesome.desktop

[Desktop Entry]
 Version=1.0
 Type=Application
 Name=Awesome
 Comment=The awesome launcher!
 TryExec=awesome
 Exec=awesome
 NoDisplay=true

Завершаем сессию пользователя и логинимся в сессию Gnome with Awesome.

Настройка

При загрузке сессии можно заметить, что под gnome-panel отрисовывается панель awesome, для наведения порядка необходимо её отключить. Для этого в файле ~/.config/awesome/rc.lua закомментируем строки4), относящиеся к wibox:

-- {{{ Wibox
-- Create a textclock widget
--mytextclock = awful.widget.textclock({ align = "right" })
--
-- Create a systray
--mysystray = widget({ type = "systray" })
--
-- Create a wibox for each screen and add it
--mywibox = {}
--mypromptbox = {}
--mylayoutbox = {}
--mytaglist = {}
--mytaglist.buttons = awful.util.table.join(
--                    awful.button({ }, 1, awful.tag.viewonly),
--                    awful.button({ modkey }, 1, awful.client.movetotag),
--                    awful.button({ }, 3, awful.tag.viewtoggle),
--                    awful.button({ modkey }, 3, awful.client.toggletag),
--                    awful.button({ }, 4, awful.tag.viewnext),
--                    awful.button({ }, 5, awful.tag.viewprev)
--                    )
--mytasklist = {}
--mytasklist.buttons = awful.util.table.join(
--                     awful.button({ }, 1, function (c)
--                                              if c == client.focus then
--                                                  c.minimized = true
--                                             else
--                                                  if not c:isvisible() then
--                                                      awful.tag.viewonly(c:tags()[1])
--                                                  end
--                                                  -- This will also un-minimize
--                                                  -- the client, if needed
--                                                  client.focus = c
--                                                  c:raise()
--                                              end
--                                          end),
--                     awful.button({ }, 3, function ()
--                                              if instance then
--                                                  instance:hide()
--                                                  instance = nil
--                                              else
--                                                  instance = awful.menu.clients({ width=250 })
--                                              end
--                                          end),
--                     awful.button({ }, 4, function ()
--                                              awful.client.focus.byidx(1)
--                                              if client.focus then client.focus:raise() end
--                                          end),
--                     awful.button({ }, 5, function ()
--                                              awful.client.focus.byidx(-1)
--                                              if client.focus then client.focus:raise() end
--                                          end))
--
--for s = 1, screen.count() do
--    -- Create a promptbox for each screen
--    mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright })
--    -- Create an imagebox widget which will contains an icon indicating which layout we're using.
--    -- We need one layoutbox per screen.
--    mylayoutbox[s] = awful.widget.layoutbox(s)
--    mylayoutbox[s]:buttons(awful.util.table.join(
--                           awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
--                           awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
--                           awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
--                           awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
--    -- Create a taglist widget
--    mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons)
--
--    -- Create a tasklist widget
--    mytasklist[s] = awful.widget.tasklist(function(c)
--                                              return awful.widget.tasklist.label.currenttags(c, s)
--                                          end, mytasklist.buttons)
--
--    -- Create the wibox
--    mywibox[s] = awful.wibox({ position = "top", screen = s })
--    -- Add widgets to the wibox - order matters
--    mywibox[s].widgets = {
--        {
--            mylauncher,
--            mytaglist[s],
--            mypromptbox[s],
--            layout = awful.widget.layout.horizontal.leftright
--        },
--        mylayoutbox[s],
--        mytextclock,
--        s == 1 and mysystray or nil,
--        mytasklist[s],
--        layout = awful.widget.layout.horizontal.rightleft
--    }
--end
-- }}}

Для применения изменений необходимо перезагрузить Awesome нажав Mod4+Control+r

Приложения и Awesome

Автозагрузка

В Awesome отсутствует поддержка автозапуска приложений, поэтому что бы настроить автозапуск при этом после перезапуска Awesome (для применения конфигурации, например) не должны запускаться вторые копии приложений. Добавляем дополнительную библиотеку- распаковываем архив5) в каталог рядом с rc.lua. Вверху rc.lua добавляем

require("utility")

и в любом удобном месте добавляем команду автозапуска:

autorun = true
 
autorunApps = --Приложения, которым нужен перезапуск при перезапуске AwesomeWM
   {
   "kbdd",
}
 
runOnceApps = --Приложения, при перезапуске которых появляется нежелательная вторая копия
   {
    "dropbox start",
    "bluetooth-applet",
    "nm-applet",
    "pidgin",
    "gnome-settings-daemon",
    "pasystray",
}
 
if autorun then
   for app = 1, #autorunApps do
      awful.util.spawn(autorunApps[app])
   end
   for app = 1, #runOnceApps do
      utility.run_once(runOnceApps[app])
   end
end
В библиотеке utility.lua вы можете найти функции, которые так же могут показаться вам полезными.

Присвоение приложению тэг по умолчанию

Еще одной удобной особенностью Awesome является возможность назначить приложению определенный тэг, для этого в конфигурационном файле необходимо добавить следующий код:

{ rule = { class = "Vlc" },
     properties = { tag = tags[1][6]} },
В поле class значение чувствительно к регистру. Что бы узнать class необходимого приложения, нужно ввести команду
xprop | grep -i class

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

Здесь в значении tags[1][6] первая цифра указывает номер дисплея, вторая- номер тэга. После этого плеер Vlc будет всегда запускаться с шестым тэгом на первом дисплее.

Pidgin в Awesome

Тайлинг

В Awesome работа с одним из самых распространенных мессенджером станет удивительно приятной и удобной! Для этого нам нужно:

  1. Настроить схему отображения клиентов на выбранном тэге;
  2. Назначить Pidgn выбранный тэг по умолчанию;
  3. Присвоить окнам чатов статус slave по умолчанию (что позволит списку контактов оставаться всегда в мастер-зоне).

Для настройки схемы отображения клиентов тэга №4 воспользуемся куском кода, приведенным выше:

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {
names = {"⠐", "⠡", "⠪", "⠵", "⠻", "⠿",},
layout = {layouts[2], layouts[2], layouts[4], layouts[2], layouts[4], layouts[2]}
}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag(tags.names, s, tags.layout)
	awful.tag.setncol(2, tags[s][4])
	awful.tag.setproperty(tags[s][4], "mwfact", 0.20)
end
-- }}}

Назначаем клиенту Pidgin тэг по умолчанию (в данном случае №4). Дополнительно к метке class клиенты могут отличаться меткой role, который так же можно посмотреть запустив:

xprop | grep -i role

Для окна списка контактов Pidgin эта метка имеет значение buddy_list, для окон чатов- conversation. Добавляя приведенный ниже код в ваш rc.lua, вы определяете открытие окна списка контактов с тэгом 4, а открытие окна чата с тэгом 4 и пометкой его как slave, что будет переносить его сразу в стэк-зону.

    { rule = { class = "Pidgin", role = "buddy_list"},
      properties = { tag = tags[1][4] } },
    { rule = { class = "Pidgin", role = "conversation"},
      properties = { tag = tags[1][4]}, callback = awful.client.setslave },

Получим следующее:

Советы по настройке

В Pidgin рекомендуется влкючить модуль «Уведомление о сообщении» и в его настройках отметить пункт «Установить подсказку СРОЧНО для оконного менеджера». В этом случае при наличии непрочитанного сообщения тэг, которым помечен Pidgin будет выделятся цветом.

Сделать клиент плавающим (floating)

Часто нужно, чтобы некоторые клиенты всегда открывались в плавающем режиме, при котором они свободно перемещаются поверх общей схемы расположения клиентов (перемещение таких окон производится при помощи Mod4+LMB, изменение размера окна- Mod4+RBM), например KeePassx. Для этого необходимо создать правило для клиента KeePassx с установкой ему режима floating.

{ rule = { class = "Keepassx" },
  properties = { floating = true } },

Отображение раскладки клавиатуры

По умолчанию в Awesome не реализована возможность отображения раскладки клавиатуры. Но это часто является необходимым, мало того, нужно что бы система отслеживала установленную раскладку для каждого открытого окна. Для этого воспользуемся пакетом kbdd.
Установка:

 sudo apt-get install kbdd

Конфигурация rc.lua.
Создаем виджет kbdwidget:

kbdwidget = widget({type = "textbox", name = "kbdwidget"})
kbdwidget.border_color = beautiful.fg_normal
kbdwidget.text = "Eng"

Конфигурируем на прослушивание DBus:

dbus.request_name("session", "ru.gentoo.kbdd") 
dbus.add_match("session", "interface='ru.gentoo.kbdd',member='layoutChanged'") 
dbus.add_signal("ru.gentoo.kbdd", function(...) 
    local data = {...} 
    local layout = data[2] 
    lts = {[0] = "Eng", [1] = "Рус"} 
    kbdwidget.text = " "..lts[layout].." " 
    end 
) 

Добавляем виджет на панель.

-- Add widgets to the wibox - order matters
    mywibox[s].widgets = {
        {
            mylauncher,
            mytaglist[s],
            mypromptbox[s],
            layout = awful.widget.layout.horizontal.leftright
        },
        mylayoutbox[s],
        kbdwidget,
        mytextclock,
        s == 1 and mysystray or nil,
        mytasklist[s],
        layout = awful.widget.layout.horizontal.rightleft
    }
end
-- }}}

Добавляем kbdd в автозагрузку

function run_once(prg)
    if not prg then
        do return nil end
    end
    awful.util.spawn_with_shell("x=" .. prg .. "; pgrep -u $USERNAME -x " .. prg .. " || (" .. prg .. ")")
end
 
run_once("kbdd")

Включение numlock при загрузке

Для этого будет использоваться программа numlockx

sudo apt-get install numlockx

В любое место rc.lua необходимо добавить строку

awful.util.spawn("numlockx on")

Проблемы

Если вы используете chromium, то обнаружите неприятную вещь: все ссылки mailto6) открываются новым окном браузера chromium, вместо положенного thunderbird. Эта проблема касается не только AwesomeWM, но и всех других нестандартных окружений рабочего стола. Возникает она в следствии того, что chromium для открытия ссылок использует команду xdg-email, которая как раз и не признает никакие другие DE кроме GNOME, KDE и LXDE, и все ссылки начинает открывать в браузере по умолчанию. Для решения данной проблемы выполняем следующие команды:

mkdir -p ~/.gconf/desktop/gnome/url-handlers/mailto
gconftool-2 --set /desktop/gnome/url-handlers/mailto/command -t string 'thunderbird %s'
gconftool-2 --set /desktop/gnome/url-handlers/mailto/enabled -t bool true 
sudo sed 's/open_generic "${mailto}"/open_gnome "${mailto}"/' -i /usr/bin/xdg-email

Последнюю команду необходимо будет повторять после каждого обновления xdg-utils или в synaptic запретить обновления.


1)
а так же все остальные вещи, настраиваемые в меню «Параметры системы», все эти настройки применяются при запуске gnome-settings-daemon отдельно или внутри сессии GNOME(см.ниже
2)
убраны номера недели и отформатирован вывод названия месяца и года, а так же добавлены комментарии на русском языке
3)
если, конечно же, они распознаются на железном уровне
4)
в языке Lua комментарий начинается с символа двойного дефис
6)
написать электронное сообщение